@danielfgray/pg-sourcerer 0.3.0 → 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/bin/pgsourcerer +2 -0
- package/dist/__tests__/fixtures/index.d.ts +15 -0
- package/dist/__tests__/fixtures/index.d.ts.map +1 -0
- package/dist/__tests__/fixtures/index.js +19 -0
- package/dist/__tests__/fixtures/index.js.map +1 -0
- package/dist/__tests__/fixtures/introspection.json +40522 -0
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +7 -46
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +38 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -2
- package/dist/config.js.map +1 -1
- package/dist/{lib/conjure.d.ts → conjure/index.d.ts} +62 -3
- package/dist/conjure/index.d.ts.map +1 -0
- package/dist/{lib/conjure.js → conjure/index.js} +124 -3
- package/dist/conjure/index.js.map +1 -0
- package/dist/conjure/signature.d.ts +85 -0
- package/dist/conjure/signature.d.ts.map +1 -0
- package/dist/conjure/signature.js +130 -0
- package/dist/conjure/signature.js.map +1 -0
- package/dist/conjure/types.d.ts +97 -0
- package/dist/conjure/types.d.ts.map +1 -0
- package/dist/conjure/types.js +206 -0
- package/dist/conjure/types.js.map +1 -0
- package/dist/errors.d.ts +114 -139
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +82 -36
- package/dist/errors.js.map +1 -1
- package/dist/generate.d.ts +45 -46
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +86 -59
- package/dist/generate.js.map +1 -1
- package/dist/hex/builder.d.ts +12 -0
- package/dist/hex/builder.d.ts.map +1 -0
- package/dist/hex/builder.js +64 -0
- package/dist/hex/builder.js.map +1 -0
- package/dist/hex/ddl.d.ts +53 -0
- package/dist/hex/ddl.d.ts.map +1 -0
- package/dist/hex/ddl.js +306 -0
- package/dist/hex/ddl.js.map +1 -0
- package/dist/hex/index.d.ts +105 -0
- package/dist/hex/index.d.ts.map +1 -0
- package/dist/hex/index.js +81 -0
- package/dist/hex/index.js.map +1 -0
- package/dist/hex/primitives.d.ts +23 -0
- package/dist/hex/primitives.d.ts.map +1 -0
- package/dist/hex/primitives.js +38 -0
- package/dist/hex/primitives.js.map +1 -0
- package/dist/hex/query.d.ts +116 -0
- package/dist/hex/query.d.ts.map +1 -0
- package/dist/hex/query.js +219 -0
- package/dist/hex/query.js.map +1 -0
- package/dist/hex/types.d.ts +287 -0
- package/dist/hex/types.d.ts.map +1 -0
- package/dist/hex/types.js +431 -0
- package/dist/hex/types.js.map +1 -0
- package/dist/index.d.ts +17 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -44
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +76 -140
- package/dist/init.js.map +1 -1
- package/dist/ir/extensions/queries.d.ts +6 -6
- package/dist/ir/extensions/queries.d.ts.map +1 -1
- package/dist/ir/extensions/queries.js +6 -4
- package/dist/ir/extensions/queries.js.map +1 -1
- package/dist/ir/extensions/schema-builder.d.ts.map +1 -1
- package/dist/ir/extensions/schema-builder.js.map +1 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js.map +1 -1
- package/dist/ir/relation-graph.d.ts.map +1 -1
- package/dist/ir/relation-graph.js +8 -8
- package/dist/ir/relation-graph.js.map +1 -1
- package/dist/ir/semantic-ir.d.ts +38 -0
- package/dist/ir/semantic-ir.d.ts.map +1 -1
- package/dist/ir/semantic-ir.js +50 -2
- package/dist/ir/semantic-ir.js.map +1 -1
- package/dist/ir/smart-tags.d.ts.map +1 -1
- package/dist/ir/smart-tags.js.map +1 -1
- package/dist/lib/field-utils.d.ts.map +1 -1
- package/dist/lib/field-utils.js +7 -7
- package/dist/lib/field-utils.js.map +1 -1
- package/dist/lib/join-graph.d.ts +95 -0
- package/dist/lib/join-graph.d.ts.map +1 -0
- package/dist/lib/join-graph.js +305 -0
- package/dist/lib/join-graph.js.map +1 -0
- package/dist/lib/picker.d.ts +60 -0
- package/dist/lib/picker.d.ts.map +1 -0
- package/dist/lib/picker.js +325 -0
- package/dist/lib/picker.js.map +1 -0
- package/dist/plugins/arktype.d.ts +20 -24
- package/dist/plugins/arktype.d.ts.map +1 -1
- package/dist/plugins/arktype.js +462 -386
- package/dist/plugins/arktype.js.map +1 -1
- package/dist/plugins/effect/http.d.ts +7 -0
- package/dist/plugins/effect/http.d.ts.map +1 -0
- package/dist/plugins/effect/http.js +460 -0
- package/dist/plugins/effect/http.js.map +1 -0
- package/dist/plugins/effect/index.d.ts +22 -0
- package/dist/plugins/effect/index.d.ts.map +1 -0
- package/dist/plugins/effect/index.js +65 -0
- package/dist/plugins/effect/index.js.map +1 -0
- package/dist/plugins/effect/models.d.ts +6 -0
- package/dist/plugins/effect/models.d.ts.map +1 -0
- package/dist/plugins/effect/models.js +116 -0
- package/dist/plugins/effect/models.js.map +1 -0
- package/dist/plugins/effect/repos.d.ts +21 -0
- package/dist/plugins/effect/repos.d.ts.map +1 -0
- package/dist/plugins/effect/repos.js +131 -0
- package/dist/plugins/effect/repos.js.map +1 -0
- package/dist/plugins/effect/schemas.d.ts +7 -0
- package/dist/plugins/effect/schemas.d.ts.map +1 -0
- package/dist/plugins/effect/schemas.js +75 -0
- package/dist/plugins/effect/schemas.js.map +1 -0
- package/dist/plugins/effect/shared.d.ts +116 -0
- package/dist/plugins/effect/shared.d.ts.map +1 -0
- package/dist/plugins/effect/shared.js +164 -0
- package/dist/plugins/effect/shared.js.map +1 -0
- package/dist/plugins/http-elysia.d.ts +20 -27
- package/dist/plugins/http-elysia.d.ts.map +1 -1
- package/dist/plugins/http-elysia.js +350 -475
- package/dist/plugins/http-elysia.js.map +1 -1
- package/dist/plugins/http-express.d.ts +20 -31
- package/dist/plugins/http-express.d.ts.map +1 -1
- package/dist/plugins/http-express.js +281 -268
- package/dist/plugins/http-express.js.map +1 -1
- package/dist/plugins/http-hono.d.ts +17 -33
- package/dist/plugins/http-hono.d.ts.map +1 -1
- package/dist/plugins/http-hono.js +317 -341
- package/dist/plugins/http-hono.js.map +1 -1
- package/dist/plugins/http-orpc.d.ts +34 -33
- package/dist/plugins/http-orpc.d.ts.map +1 -1
- package/dist/plugins/http-orpc.js +345 -257
- package/dist/plugins/http-orpc.js.map +1 -1
- package/dist/plugins/http-trpc.d.ts +33 -35
- package/dist/plugins/http-trpc.d.ts.map +1 -1
- package/dist/plugins/http-trpc.js +337 -241
- package/dist/plugins/http-trpc.js.map +1 -1
- package/dist/plugins/kysely.d.ts +54 -59
- package/dist/plugins/kysely.d.ts.map +1 -1
- package/dist/plugins/kysely.js +826 -687
- package/dist/plugins/kysely.js.map +1 -1
- package/dist/plugins/sql-queries.d.ts +38 -44
- package/dist/plugins/sql-queries.d.ts.map +1 -1
- package/dist/plugins/sql-queries.js +497 -897
- package/dist/plugins/sql-queries.js.map +1 -1
- package/dist/plugins/types.d.ts +12 -20
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/plugins/types.js +84 -227
- package/dist/plugins/types.js.map +1 -1
- package/dist/plugins/valibot.d.ts +7 -44
- package/dist/plugins/valibot.d.ts.map +1 -1
- package/dist/plugins/valibot.js +376 -382
- package/dist/plugins/valibot.js.map +1 -1
- package/dist/plugins/zod.d.ts +20 -24
- package/dist/plugins/zod.d.ts.map +1 -1
- package/dist/plugins/zod.js +370 -367
- package/dist/plugins/zod.js.map +1 -1
- package/dist/runtime/emit.d.ts +64 -0
- package/dist/runtime/emit.d.ts.map +1 -0
- package/dist/runtime/emit.js +445 -0
- package/dist/runtime/emit.js.map +1 -0
- package/dist/runtime/errors.d.ts +36 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.js +29 -0
- package/dist/runtime/errors.js.map +1 -0
- package/dist/runtime/file-assignment.d.ts +161 -0
- package/dist/runtime/file-assignment.d.ts.map +1 -0
- package/dist/runtime/file-assignment.js +195 -0
- package/dist/runtime/file-assignment.js.map +1 -0
- package/dist/runtime/orchestrator.d.ts +62 -0
- package/dist/runtime/orchestrator.d.ts.map +1 -0
- package/dist/runtime/orchestrator.js +99 -0
- package/dist/runtime/orchestrator.js.map +1 -0
- package/dist/runtime/registry.d.ts +268 -0
- package/dist/runtime/registry.d.ts.map +1 -0
- package/dist/runtime/registry.js +436 -0
- package/dist/runtime/registry.js.map +1 -0
- package/dist/runtime/types.d.ts +182 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +2 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/runtime/validation.d.ts +41 -0
- package/dist/runtime/validation.d.ts.map +1 -0
- package/dist/runtime/validation.js +70 -0
- package/dist/runtime/validation.js.map +1 -0
- package/dist/services/config-loader.d.ts.map +1 -1
- package/dist/services/config-loader.js +15 -6
- package/dist/services/config-loader.js.map +1 -1
- package/dist/services/config.d.ts +55 -25
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +60 -34
- package/dist/services/config.js.map +1 -1
- package/dist/services/file-writer.d.ts +3 -3
- package/dist/services/file-writer.d.ts.map +1 -1
- package/dist/services/file-writer.js +6 -8
- package/dist/services/file-writer.js.map +1 -1
- package/dist/services/inflection.d.ts +126 -27
- package/dist/services/inflection.d.ts.map +1 -1
- package/dist/services/inflection.js +300 -72
- package/dist/services/inflection.js.map +1 -1
- package/dist/services/introspection.d.ts.map +1 -1
- package/dist/services/introspection.js +6 -6
- package/dist/services/introspection.js.map +1 -1
- package/dist/services/ir-builder.d.ts.map +1 -1
- package/dist/services/ir-builder.js +73 -77
- package/dist/services/ir-builder.js.map +1 -1
- package/dist/services/ir.d.ts.map +1 -1
- package/dist/services/ir.js.map +1 -1
- package/dist/services/pg-types.d.ts.map +1 -1
- package/dist/services/pg-types.js +3 -3
- package/dist/services/pg-types.js.map +1 -1
- package/dist/services/smart-tags-parser.d.ts.map +1 -1
- package/dist/services/smart-tags-parser.js +4 -4
- package/dist/services/smart-tags-parser.js.map +1 -1
- package/dist/services/type-hints.d.ts.map +1 -1
- package/dist/services/type-hints.js +1 -1
- package/dist/services/type-hints.js.map +1 -1
- package/dist/services/user-module-parser.d.ts +46 -0
- package/dist/services/user-module-parser.d.ts.map +1 -0
- package/dist/services/user-module-parser.js +181 -0
- package/dist/services/user-module-parser.js.map +1 -0
- package/dist/shared/converters.d.ts +60 -0
- package/dist/shared/converters.d.ts.map +1 -0
- package/dist/shared/converters.js +168 -0
- package/dist/shared/converters.js.map +1 -0
- package/dist/shared/query-types.d.ts +95 -0
- package/dist/shared/query-types.d.ts.map +1 -0
- package/dist/shared/query-types.js +9 -0
- package/dist/shared/query-types.js.map +1 -0
- package/dist/testing.d.ts +125 -37
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +134 -42
- package/dist/testing.js.map +1 -1
- package/dist/user-module.d.ts +86 -0
- package/dist/user-module.d.ts.map +1 -0
- package/dist/user-module.js +55 -0
- package/dist/user-module.js.map +1 -0
- package/package.json +10 -6
- package/dist/lib/conjure.d.ts.map +0 -1
- package/dist/lib/conjure.js.map +0 -1
- package/dist/lib/hex.d.ts +0 -119
- package/dist/lib/hex.d.ts.map +0 -1
- package/dist/lib/hex.js +0 -188
- package/dist/lib/hex.js.map +0 -1
- package/dist/plugins/effect.d.ts +0 -53
- package/dist/plugins/effect.d.ts.map +0 -1
- package/dist/plugins/effect.js +0 -1074
- package/dist/plugins/effect.js.map +0 -1
- package/dist/plugins/kysely/queries.d.ts +0 -92
- package/dist/plugins/kysely/queries.d.ts.map +0 -1
- package/dist/plugins/kysely/queries.js +0 -1169
- package/dist/plugins/kysely/queries.js.map +0 -1
- package/dist/plugins/kysely/shared.d.ts +0 -59
- package/dist/plugins/kysely/shared.d.ts.map +0 -1
- package/dist/plugins/kysely/shared.js +0 -247
- package/dist/plugins/kysely/shared.js.map +0 -1
- package/dist/plugins/kysely/types.d.ts +0 -22
- package/dist/plugins/kysely/types.d.ts.map +0 -1
- package/dist/plugins/kysely/types.js +0 -428
- package/dist/plugins/kysely/types.js.map +0 -1
- package/dist/services/artifact-store.d.ts +0 -65
- package/dist/services/artifact-store.d.ts.map +0 -1
- package/dist/services/artifact-store.js +0 -57
- package/dist/services/artifact-store.js.map +0 -1
- package/dist/services/core-providers.d.ts +0 -15
- package/dist/services/core-providers.d.ts.map +0 -1
- package/dist/services/core-providers.js +0 -23
- package/dist/services/core-providers.js.map +0 -1
- package/dist/services/emissions.d.ts +0 -103
- package/dist/services/emissions.d.ts.map +0 -1
- package/dist/services/emissions.js +0 -241
- package/dist/services/emissions.js.map +0 -1
- package/dist/services/execution.d.ts +0 -35
- package/dist/services/execution.d.ts.map +0 -1
- package/dist/services/execution.js +0 -86
- package/dist/services/execution.js.map +0 -1
- package/dist/services/file-builder.d.ts +0 -85
- package/dist/services/file-builder.d.ts.map +0 -1
- package/dist/services/file-builder.js +0 -112
- package/dist/services/file-builder.js.map +0 -1
- package/dist/services/plugin-meta.d.ts +0 -33
- package/dist/services/plugin-meta.d.ts.map +0 -1
- package/dist/services/plugin-meta.js +0 -24
- package/dist/services/plugin-meta.js.map +0 -1
- package/dist/services/plugin-runner.d.ts +0 -42
- package/dist/services/plugin-runner.d.ts.map +0 -1
- package/dist/services/plugin-runner.js +0 -84
- package/dist/services/plugin-runner.js.map +0 -1
- package/dist/services/plugin.d.ts +0 -421
- package/dist/services/plugin.d.ts.map +0 -1
- package/dist/services/plugin.js +0 -197
- package/dist/services/plugin.js.map +0 -1
- package/dist/services/resolution.d.ts +0 -38
- package/dist/services/resolution.d.ts.map +0 -1
- package/dist/services/resolution.js +0 -242
- package/dist/services/resolution.js.map +0 -1
- package/dist/services/service-registry.d.ts +0 -74
- package/dist/services/service-registry.d.ts.map +0 -1
- package/dist/services/service-registry.js +0 -61
- package/dist/services/service-registry.js.map +0 -1
- package/dist/services/symbols.d.ts +0 -144
- package/dist/services/symbols.d.ts.map +0 -1
- package/dist/services/symbols.js +0 -144
- package/dist/services/symbols.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -4,13 +4,23 @@
|
|
|
4
4
|
* Main entry point
|
|
5
5
|
*/
|
|
6
6
|
// Config
|
|
7
|
-
export { Config, TypeHint, TypeHintMatch } from "./config.js";
|
|
7
|
+
export { Config, TypeHint, TypeHintMatch, } from "./config.js";
|
|
8
8
|
// Config Loader Service
|
|
9
9
|
export { ConfigLoaderService, ConfigLoaderLive, createConfigLoader, defineConfig, } from "./services/config-loader.js";
|
|
10
10
|
// Config Service (Effect DI)
|
|
11
|
-
export {
|
|
11
|
+
export {
|
|
12
|
+
// Service tag
|
|
13
|
+
ConfigService, FileConfigProvider, InMemoryConfigProvider, withFallback,
|
|
14
|
+
// Layer constructors
|
|
15
|
+
ConfigFromFile, ConfigFromMemory, ConfigTest, ConfigWithFallback,
|
|
16
|
+
// Utilities
|
|
17
|
+
getConfigSearchPaths, } from "./services/config.js";
|
|
12
18
|
// Errors
|
|
13
19
|
export * from "./errors.js";
|
|
20
|
+
// User Module References
|
|
21
|
+
export { userModule, isUserModuleRef } from "./user-module.js";
|
|
22
|
+
// User Module Parser Service
|
|
23
|
+
export { UserModuleParserService, UserModuleParserLive, createUserModuleParser, } from "./services/user-module-parser.js";
|
|
14
24
|
// IR
|
|
15
25
|
export { createIRBuilder, freezeIR,
|
|
16
26
|
// Type guards
|
|
@@ -20,58 +30,37 @@ getTableEntities, getEnumEntities, getDomainEntities, getCompositeEntities, getF
|
|
|
20
30
|
export { SmartTags, ShapeKind } from "./ir/index.js";
|
|
21
31
|
// IR Extensions - Contracts between providers
|
|
22
32
|
export { EntityQueriesExtension as EntityQueriesExtensionSchema, FunctionsExtension as FunctionsExtensionSchema, } from "./ir/extensions/queries.js";
|
|
33
|
+
// IR Extensions - Schema Builder Contract
|
|
34
|
+
export { SCHEMA_BUILDER_KIND, } from "./ir/extensions/schema-builder.js";
|
|
23
35
|
// Services - IR
|
|
24
36
|
export { IR } from "./services/ir.js";
|
|
25
|
-
// Services - Artifact Store
|
|
26
|
-
export { ArtifactStore, createArtifactStore, ArtifactStoreLive } from "./services/artifact-store.js";
|
|
27
|
-
// Services - Plugin Meta
|
|
28
|
-
export { PluginMeta } from "./services/plugin-meta.js";
|
|
29
|
-
// Services - Plugin Types (new plugin API)
|
|
30
|
-
export { PluginNotFound, PluginCycle, PluginExecutionFailed, ResourceNotResolved, Plugins, PluginsLive, definePlugin, createPluginRegistry, } from "./services/plugin.js";
|
|
31
37
|
// Services - Inflection
|
|
32
38
|
export { Inflection, inflect, defaultInflection, defaultTransforms, createInflection, makeInflectionLayer, composeInflectionConfigs, composeInflection, InflectionLive, } from "./services/inflection.js";
|
|
33
39
|
// Services - Type Hints
|
|
34
40
|
export { TypeHints, createTypeHintRegistry, emptyTypeHintRegistry, TypeHintsLive, } from "./services/type-hints.js";
|
|
35
41
|
// Services - PostgreSQL Type Mapping
|
|
36
42
|
export { PgTypeOid, TsType, ExtensionTypeMap, defaultPgToTs, getExtensionTypeMapping, composeMappers, wrapArrayType, wrapNullable, findEnumByPgName, findCompositeByPgName, } from "./services/pg-types.js";
|
|
37
|
-
// Services -
|
|
38
|
-
export {
|
|
39
|
-
//
|
|
40
|
-
export {
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
export {
|
|
45
|
-
// Services - File Writer
|
|
46
|
-
export { FileWriterSvc, createFileWriter, FileWriterLive, } from "./services/file-writer.js";
|
|
47
|
-
// Services - Smart Tags Parser
|
|
48
|
-
export { parseSmartTags, } from "./services/smart-tags-parser.js";
|
|
49
|
-
// Services - IR Builder
|
|
50
|
-
export { IRBuilderSvc, IRBuilderLive, createIRBuilderService, } from "./services/ir-builder.js";
|
|
51
|
-
// Testing utilities
|
|
52
|
-
export { PluginTestLayers, createPluginTestLayer, } from "./testing.js";
|
|
53
|
-
// Conjure - AST builder DSL
|
|
54
|
-
export { conjure, cast, } from "./lib/conjure.js";
|
|
55
|
-
// Hex - SQL query building primitives
|
|
56
|
-
export { hex, buildTemplateLiteral, buildAwaitSqlTag, buildAwaitSqlString, buildQuery, buildFirstRowDecl, buildAllRowsDecl, buildReturnQuery, } from "./lib/hex.js";
|
|
57
|
-
// Plugins (new API)
|
|
58
|
-
export { typesPlugin, types } from "./plugins/types.js";
|
|
43
|
+
// Services - File Assignment
|
|
44
|
+
export { parseCapabilityInfo, } from "./runtime/file-assignment.js";
|
|
45
|
+
// Runtime Emit
|
|
46
|
+
export { emitFiles, } from "./runtime/emit.js";
|
|
47
|
+
// =============================================================================
|
|
48
|
+
// Plugins
|
|
49
|
+
// =============================================================================
|
|
50
|
+
export { typesPlugin } from "./plugins/types.js";
|
|
59
51
|
export { zod } from "./plugins/zod.js";
|
|
60
52
|
export { arktype } from "./plugins/arktype.js";
|
|
61
53
|
export { valibot } from "./plugins/valibot.js";
|
|
62
|
-
export {
|
|
63
|
-
|
|
64
|
-
export {
|
|
65
|
-
|
|
54
|
+
export { effect } from "./plugins/effect/index.js";
|
|
55
|
+
export { express } from "./plugins/http-express.js";
|
|
56
|
+
export { elysia } from "./plugins/http-elysia.js";
|
|
57
|
+
export { hono } from "./plugins/http-hono.js";
|
|
66
58
|
export { kysely } from "./plugins/kysely.js";
|
|
67
|
-
|
|
68
|
-
export {
|
|
69
|
-
export {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
export { generate, runGenerate, GenerateLive, } from "./generate.js";
|
|
75
|
-
// Database introspection
|
|
76
|
-
export { DatabaseIntrospectionService, DatabaseIntrospectionLive, createDatabaseIntrospection, introspectDatabase, } from "./services/introspection.js";
|
|
59
|
+
export { sqlQueries } from "./plugins/sql-queries.js";
|
|
60
|
+
export { orpc } from "./plugins/http-orpc.js";
|
|
61
|
+
export { trpc } from "./plugins/http-trpc.js";
|
|
62
|
+
// =============================================================================
|
|
63
|
+
// Testing Utilities
|
|
64
|
+
// =============================================================================
|
|
65
|
+
export { testIR, testIRWithEntities, testIRFromFixture, testConfig, testPlugin, testPluginEmit, } from "./testing.js";
|
|
77
66
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,SAAS;AACT,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAkB,MAAM,EAAkC,MAAM,QAAQ,CAAC;AA0chF,eAAO,MAAM,OAAO;;qGAoDlB,CAAC"}
|
package/dist/init.js
CHANGED
|
@@ -2,92 +2,72 @@
|
|
|
2
2
|
* pg-sourcerer init command
|
|
3
3
|
*
|
|
4
4
|
* Interactive config generator using @effect/cli Prompt.
|
|
5
|
-
* Uses conjure AST builder to generate the config file.
|
|
6
5
|
*/
|
|
7
6
|
import { Prompt } from "@effect/cli";
|
|
8
7
|
import { FileSystem } from "@effect/platform";
|
|
9
8
|
import { Array, Console, Effect, HashMap, HashSet, Option, pipe } from "effect";
|
|
10
9
|
import postgres from "postgres";
|
|
11
|
-
import { conjure } from "./lib/conjure.js";
|
|
12
|
-
import recast from "recast";
|
|
13
10
|
import { introspectDatabase } from "./services/introspection.js";
|
|
14
|
-
|
|
11
|
+
import { conjure } from "./conjure/index.js";
|
|
12
|
+
/** Maps plugin selection values to their import names from pg-sourcerer */
|
|
15
13
|
const pluginImportNames = {
|
|
16
|
-
|
|
14
|
+
// Type generators
|
|
15
|
+
types: "typesPlugin",
|
|
17
16
|
zod: "zod",
|
|
18
|
-
arktype: "
|
|
17
|
+
arktype: "arktype",
|
|
19
18
|
effect: "effect",
|
|
19
|
+
valibot: "valibot",
|
|
20
|
+
// Kysely
|
|
21
|
+
"kysely-types": "kysely",
|
|
22
|
+
"kysely-queries": "kysely",
|
|
23
|
+
// SQL queries
|
|
20
24
|
"sql-queries": "sqlQueries",
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"http-
|
|
24
|
-
"http-
|
|
25
|
-
"http-
|
|
25
|
+
// HTTP frameworks
|
|
26
|
+
"http-elysia": "elysia",
|
|
27
|
+
"http-express": "express",
|
|
28
|
+
"http-hono": "hono",
|
|
29
|
+
"http-trpc": "trpc",
|
|
30
|
+
"http-orpc": "orpc",
|
|
26
31
|
};
|
|
27
|
-
/** Get plugin info by value */
|
|
28
32
|
const getPluginInfo = (value) => {
|
|
29
33
|
const importName = pluginImportNames[value];
|
|
30
34
|
return importName ? { value, importName } : undefined;
|
|
31
35
|
};
|
|
32
36
|
const POSTGRES_URL_REGEX = /^postgres(ql)?:\/\//i;
|
|
33
|
-
|
|
34
|
-
* Parse .env content into HashMap<string, string>
|
|
35
|
-
* Handles: KEY=value, KEY="value", KEY='value', comments, empty lines
|
|
36
|
-
*/
|
|
37
|
-
const parseDotEnv = (content) => pipe(content.split("\n"), Array.map(line => line.trim()), Array.filter(line => line.length > 0 && !line.startsWith("#")), Array.filterMap(line => {
|
|
37
|
+
const parseDotEnv = (content) => pipe(content.split("\n"), Array.map((line) => line.trim()), Array.filter((line) => line.length > 0 && !line.startsWith("#")), Array.filterMap((line) => {
|
|
38
38
|
const eqIndex = line.indexOf("=");
|
|
39
39
|
if (eqIndex === -1)
|
|
40
40
|
return Option.none();
|
|
41
41
|
const key = line.slice(0, eqIndex).trim();
|
|
42
42
|
let value = line.slice(eqIndex + 1).trim();
|
|
43
|
-
|
|
44
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
45
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
43
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
46
44
|
value = value.slice(1, -1);
|
|
47
45
|
}
|
|
48
46
|
return Option.some([key, value]);
|
|
49
47
|
}), HashMap.fromIterable);
|
|
50
|
-
|
|
51
|
-
* Filter entries matching postgres URL pattern
|
|
52
|
-
*/
|
|
53
|
-
const filterPostgresUrls = (entries, source) => pipe(entries, HashMap.filter(value => POSTGRES_URL_REGEX.test(value)), HashMap.toEntries, Array.map(([key, value]) => ({ key, value, source })));
|
|
54
|
-
/**
|
|
55
|
-
* Get process.env as HashMap, excluding specified keys
|
|
56
|
-
*/
|
|
48
|
+
const filterPostgresUrls = (entries, source) => pipe(entries, HashMap.filter((value) => POSTGRES_URL_REGEX.test(value)), HashMap.toEntries, Array.map(([key, value]) => ({ key, value, source })));
|
|
57
49
|
const processEnvExcluding = (exclude) => pipe(Object.entries(process.env), Array.filter(([key, value]) => value != null && !HashSet.has(exclude, key)), Array.map(([key, value]) => [key, value]), HashMap.fromIterable);
|
|
58
|
-
/**
|
|
59
|
-
* Scan .env file and process.env for postgres connection strings.
|
|
60
|
-
*/
|
|
61
50
|
const scanEnvForConnectionStrings = Effect.gen(function* () {
|
|
62
51
|
const fs = yield* FileSystem.FileSystem;
|
|
63
52
|
const envPath = `${process.cwd()}/.env`;
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
// Scan process.env, excluding keys already found in .env
|
|
67
|
-
const dotEnvKeys = pipe(dotEnvMatches, Array.map(m => m.key), HashSet.fromIterable);
|
|
53
|
+
const dotEnvMatches = yield* fs.readFileString(envPath).pipe(Effect.map((content) => filterPostgresUrls(parseDotEnv(content), ".env")), Effect.catchAll(() => Effect.succeed([])));
|
|
54
|
+
const dotEnvKeys = pipe(dotEnvMatches, Array.map((m) => m.key), HashSet.fromIterable);
|
|
68
55
|
const processEnvMatches = filterPostgresUrls(processEnvExcluding(dotEnvKeys), "process.env");
|
|
69
56
|
return [...dotEnvMatches, ...processEnvMatches];
|
|
70
57
|
});
|
|
71
|
-
// ============================================================================
|
|
72
|
-
// Prompts
|
|
73
|
-
// ============================================================================
|
|
74
58
|
const connectionStringPrompt = Prompt.text({
|
|
75
59
|
message: "Database connection string",
|
|
76
|
-
validate: value => value.trim().length === 0
|
|
60
|
+
validate: (value) => value.trim().length === 0
|
|
77
61
|
? Effect.fail("Connection string is required")
|
|
78
62
|
: Effect.succeed(value.trim()),
|
|
79
63
|
});
|
|
80
|
-
/**
|
|
81
|
-
* Prompt for connection string and immediately test it.
|
|
82
|
-
* Re-prompts on failure until successful.
|
|
83
|
-
*/
|
|
84
64
|
const promptAndTestConnection = (defaultValue) => Effect.gen(function* () {
|
|
85
65
|
const prompt = defaultValue
|
|
86
66
|
? Prompt.text({ message: "Database connection string", default: defaultValue })
|
|
87
67
|
: connectionStringPrompt;
|
|
88
68
|
const connStr = yield* prompt;
|
|
89
69
|
yield* Console.log("Testing connection...");
|
|
90
|
-
const result = yield* testConnection(connStr).pipe(Effect.map(version => ({ success: true, version })), Effect.catchAll(e => Effect.succeed({ success: false, error: e.message })));
|
|
70
|
+
const result = yield* testConnection(connStr).pipe(Effect.map((version) => ({ success: true, version })), Effect.catchAll((e) => Effect.succeed({ success: false, error: e.message })));
|
|
91
71
|
if (result.success) {
|
|
92
72
|
yield* Console.log(`✓ Connected to ${result.version}\n`);
|
|
93
73
|
return connStr;
|
|
@@ -95,22 +75,17 @@ const promptAndTestConnection = (defaultValue) => Effect.gen(function* () {
|
|
|
95
75
|
else {
|
|
96
76
|
yield* Console.error(`✗ ${result.error}`);
|
|
97
77
|
yield* Console.log("Please try again.\n");
|
|
98
|
-
// On retry, use the failed value as the new default so user can edit it
|
|
99
78
|
return yield* promptAndTestConnection(connStr);
|
|
100
79
|
}
|
|
101
80
|
});
|
|
102
|
-
/**
|
|
103
|
-
* Get connection string - either from detected env var or manual entry.
|
|
104
|
-
*/
|
|
105
81
|
const getConnectionString = Effect.gen(function* () {
|
|
106
82
|
const envMatches = yield* scanEnvForConnectionStrings;
|
|
107
|
-
// No matches → manual entry
|
|
108
83
|
if (Array.isEmptyReadonlyArray(envMatches)) {
|
|
109
84
|
const connectionString = yield* promptAndTestConnection();
|
|
110
85
|
return { connectionString, configValue: connectionString, isEnvRef: false };
|
|
111
86
|
}
|
|
112
87
|
yield* Console.log(`Found ${envMatches.length} potential connection string${envMatches.length === 1 ? "" : "s"} in environment:\n`);
|
|
113
|
-
const choices = pipe(envMatches, Array.map(m => ({
|
|
88
|
+
const choices = pipe(envMatches, Array.map((m) => ({
|
|
114
89
|
title: `${m.key} (${m.source})`,
|
|
115
90
|
value: m.key,
|
|
116
91
|
})), Array.append({ title: "Enter manually", value: "__manual__" }));
|
|
@@ -122,10 +97,9 @@ const getConnectionString = Effect.gen(function* () {
|
|
|
122
97
|
const connectionString = yield* promptAndTestConnection();
|
|
123
98
|
return { connectionString, configValue: connectionString, isEnvRef: false };
|
|
124
99
|
}
|
|
125
|
-
|
|
126
|
-
const match = pipe(envMatches, Array.findFirst(m => m.key === selected), Option.getOrThrow);
|
|
100
|
+
const match = pipe(envMatches, Array.findFirst((m) => m.key === selected), Option.getOrThrow);
|
|
127
101
|
yield* Console.log(`\nTesting ${match.key}...`);
|
|
128
|
-
const testResult = yield* testConnection(match.value).pipe(Effect.map(version => ({ success: true, version })), Effect.catchAll(e => Effect.succeed({ success: false, error: e.message })));
|
|
102
|
+
const testResult = yield* testConnection(match.value).pipe(Effect.map((version) => ({ success: true, version })), Effect.catchAll((e) => Effect.succeed({ success: false, error: e.message })));
|
|
129
103
|
if (testResult.success) {
|
|
130
104
|
yield* Console.log(`✓ Connected to ${testResult.version}\n`);
|
|
131
105
|
return {
|
|
@@ -134,25 +108,16 @@ const getConnectionString = Effect.gen(function* () {
|
|
|
134
108
|
isEnvRef: true,
|
|
135
109
|
};
|
|
136
110
|
}
|
|
137
|
-
// Failed → fall back to manual with value as default
|
|
138
111
|
yield* Console.error(`✗ ${testResult.error}`);
|
|
139
112
|
yield* Console.log("Connection failed. Please enter manually.\n");
|
|
140
113
|
const connectionString = yield* promptAndTestConnection(match.value);
|
|
141
114
|
return { connectionString, configValue: connectionString, isEnvRef: false };
|
|
142
115
|
});
|
|
143
|
-
/**
|
|
144
|
-
* Role prompt with explanation of when to use it.
|
|
145
|
-
*
|
|
146
|
-
* If using Row Level Security (RLS), set this to the role your app connects as.
|
|
147
|
-
* This ensures generated types only include columns/tables visible to that role.
|
|
148
|
-
* Leave empty if not using RLS or connecting as a superuser.
|
|
149
|
-
*/
|
|
150
116
|
const makeRolePrompt = () => Prompt.text({
|
|
151
117
|
message: "PostgreSQL role (for RLS - leave empty if not using RLS)",
|
|
152
118
|
default: "",
|
|
153
|
-
}).pipe(Prompt.map(s => s.trim() || undefined));
|
|
119
|
+
}).pipe(Prompt.map((s) => s.trim() || undefined));
|
|
154
120
|
const makeSchemasPrompt = (introspection) => {
|
|
155
|
-
// Group classes by schema and count tables/views
|
|
156
121
|
const schemaCounts = new Map();
|
|
157
122
|
for (const c of introspection.classes) {
|
|
158
123
|
if (c.relkind !== "r" && c.relkind !== "v" && c.relkind !== "m")
|
|
@@ -162,7 +127,6 @@ const makeSchemasPrompt = (introspection) => {
|
|
|
162
127
|
continue;
|
|
163
128
|
schemaCounts.set(schema, (schemaCounts.get(schema) ?? 0) + 1);
|
|
164
129
|
}
|
|
165
|
-
// Sort: public first, then by count desc
|
|
166
130
|
const schemas = [...schemaCounts.entries()].sort((a, b) => {
|
|
167
131
|
if (a[0] === "public")
|
|
168
132
|
return -1;
|
|
@@ -171,16 +135,14 @@ const makeSchemasPrompt = (introspection) => {
|
|
|
171
135
|
return b[1] - a[1];
|
|
172
136
|
});
|
|
173
137
|
if (schemas.length === 0) {
|
|
174
|
-
// Fallback to text prompt if no schemas found
|
|
175
138
|
return Prompt.text({
|
|
176
139
|
message: "Schemas to introspect (comma-separated)",
|
|
177
140
|
default: "public",
|
|
178
|
-
}).pipe(Prompt.map(s => s
|
|
141
|
+
}).pipe(Prompt.map((s) => s
|
|
179
142
|
.split(",")
|
|
180
|
-
.map(x => x.trim())
|
|
181
|
-
.filter(x => x.length > 0)));
|
|
143
|
+
.map((x) => x.trim())
|
|
144
|
+
.filter((x) => x.length > 0)));
|
|
182
145
|
}
|
|
183
|
-
// Multi-select with table counts
|
|
184
146
|
return Prompt.multiSelect({
|
|
185
147
|
message: "Select schemas to introspect",
|
|
186
148
|
choices: schemas.map(([name, count]) => ({
|
|
@@ -192,26 +154,14 @@ const makeSchemasPrompt = (introspection) => {
|
|
|
192
154
|
};
|
|
193
155
|
const makeOutputDirPrompt = () => Prompt.text({
|
|
194
156
|
message: "Output directory",
|
|
195
|
-
default: "./generated",
|
|
157
|
+
default: "./src/generated",
|
|
196
158
|
});
|
|
197
|
-
/**
|
|
198
|
-
* Plugin selection with Kysely-aware branching.
|
|
199
|
-
*
|
|
200
|
-
* Flow:
|
|
201
|
-
* 1. Kysely? → yes: checkboxes for types + kysely-queries → HTTP plugins → exit
|
|
202
|
-
* 2. No Kysely → raw types or schema-driven?
|
|
203
|
-
* 3. If schema-driven → select schema lib (zod/arktype/effect)
|
|
204
|
-
* 4. Query plugins (optional multiselect, currently just sql-queries)
|
|
205
|
-
* 5. HTTP/RPC framework (optional)
|
|
206
|
-
*/
|
|
207
159
|
const makePluginsPrompt = () => Effect.gen(function* () {
|
|
208
|
-
// Step 1: Kysely gateway
|
|
209
160
|
const usesKysely = yield* Prompt.confirm({
|
|
210
161
|
message: "Do you use Kysely?",
|
|
211
162
|
initial: false,
|
|
212
163
|
});
|
|
213
164
|
if (usesKysely) {
|
|
214
|
-
// Kysely path: checkboxes, both pre-selected
|
|
215
165
|
const kyselyPlugins = yield* Prompt.multiSelect({
|
|
216
166
|
message: "Select Kysely plugins",
|
|
217
167
|
choices: [
|
|
@@ -219,22 +169,25 @@ const makePluginsPrompt = () => Effect.gen(function* () {
|
|
|
219
169
|
{ title: "kysely-queries - Query builders", value: "kysely-queries", selected: true },
|
|
220
170
|
],
|
|
221
171
|
});
|
|
222
|
-
// Step 5: HTTP/RPC framework (only show if queries selected)
|
|
223
172
|
const hasQueries = kyselyPlugins.includes("kysely-queries");
|
|
224
173
|
if (hasQueries) {
|
|
225
|
-
const
|
|
174
|
+
const httpPlugin = yield* Prompt.select({
|
|
226
175
|
message: "HTTP/RPC framework (optional, requires query plugin)",
|
|
227
176
|
choices: [
|
|
228
|
-
{ title: "
|
|
229
|
-
{ title: "
|
|
230
|
-
{ title: "
|
|
177
|
+
{ title: "None", value: "" },
|
|
178
|
+
{ title: "Elysia routes", value: "http-elysia" },
|
|
179
|
+
{ title: "Express routes", value: "http-express" },
|
|
180
|
+
{ title: "Hono routes", value: "http-hono" },
|
|
181
|
+
{ title: "tRPC router", value: "http-trpc" },
|
|
182
|
+
{ title: "oRPC router", value: "http-orpc" },
|
|
231
183
|
],
|
|
232
184
|
});
|
|
233
|
-
return
|
|
185
|
+
return httpPlugin
|
|
186
|
+
? [...kyselyPlugins, httpPlugin]
|
|
187
|
+
: kyselyPlugins;
|
|
234
188
|
}
|
|
235
189
|
return kyselyPlugins;
|
|
236
190
|
}
|
|
237
|
-
// Step 2: Raw vs schema-driven
|
|
238
191
|
const typeApproach = yield* Prompt.select({
|
|
239
192
|
message: "How do you want your types generated?",
|
|
240
193
|
choices: [
|
|
@@ -247,34 +200,36 @@ const makePluginsPrompt = () => Effect.gen(function* () {
|
|
|
247
200
|
typePlugin = "types";
|
|
248
201
|
}
|
|
249
202
|
else {
|
|
250
|
-
// Step 3: Schema library selection
|
|
251
203
|
typePlugin = yield* Prompt.select({
|
|
252
204
|
message: "Select schema library",
|
|
253
205
|
choices: [
|
|
254
206
|
{ title: "Zod", value: "zod" },
|
|
255
207
|
{ title: "ArkType", value: "arktype" },
|
|
256
|
-
{ title: "Effect Schema
|
|
208
|
+
{ title: "Effect Schema", value: "effect" },
|
|
257
209
|
],
|
|
258
210
|
});
|
|
259
211
|
}
|
|
260
|
-
// Step 4: Query plugins (optional multiselect, future-proof)
|
|
261
212
|
const queryPlugins = yield* Prompt.multiSelect({
|
|
262
213
|
message: "Query generation (optional)",
|
|
263
214
|
choices: [
|
|
264
215
|
{ title: "sql-queries - Raw SQL query functions", value: "sql-queries", selected: false },
|
|
265
216
|
],
|
|
266
217
|
});
|
|
267
|
-
// Step 5: HTTP/RPC framework (only show if queries selected)
|
|
268
218
|
if (queryPlugins.length > 0) {
|
|
269
|
-
const
|
|
219
|
+
const httpPlugin = yield* Prompt.select({
|
|
270
220
|
message: "HTTP/RPC framework (optional)",
|
|
271
221
|
choices: [
|
|
272
|
-
{ title: "
|
|
273
|
-
{ title: "
|
|
274
|
-
{ title: "
|
|
222
|
+
{ title: "None", value: "" },
|
|
223
|
+
{ title: "Elysia routes", value: "http-elysia" },
|
|
224
|
+
{ title: "Express routes", value: "http-express" },
|
|
225
|
+
{ title: "Hono routes", value: "http-hono" },
|
|
226
|
+
{ title: "tRPC router", value: "http-trpc" },
|
|
227
|
+
{ title: "oRPC router", value: "http-orpc" },
|
|
275
228
|
],
|
|
276
229
|
});
|
|
277
|
-
return
|
|
230
|
+
return httpPlugin
|
|
231
|
+
? [typePlugin, ...queryPlugins, httpPlugin]
|
|
232
|
+
: [typePlugin, ...queryPlugins];
|
|
278
233
|
}
|
|
279
234
|
return [typePlugin, ...queryPlugins];
|
|
280
235
|
});
|
|
@@ -282,16 +237,12 @@ const makeFormatterPrompt = () => Prompt.text({
|
|
|
282
237
|
message: "Formatter command (optional, leave empty to skip)",
|
|
283
238
|
default: "",
|
|
284
239
|
});
|
|
285
|
-
// ============================================================================
|
|
286
|
-
// Connection Test
|
|
287
|
-
// ============================================================================
|
|
288
240
|
const testConnection = (connectionString) => Effect.tryPromise({
|
|
289
241
|
try: async () => {
|
|
290
242
|
const sql = postgres(connectionString, { max: 1 });
|
|
291
243
|
try {
|
|
292
244
|
const result = await sql `SELECT version()`;
|
|
293
245
|
const version = result[0]?.["version"];
|
|
294
|
-
// Extract just the version number (e.g., "PostgreSQL 15.2")
|
|
295
246
|
const match = version.match(/PostgreSQL [\d.]+/);
|
|
296
247
|
return match?.[0] ?? "PostgreSQL";
|
|
297
248
|
}
|
|
@@ -299,68 +250,60 @@ const testConnection = (connectionString) => Effect.tryPromise({
|
|
|
299
250
|
await sql.end();
|
|
300
251
|
}
|
|
301
252
|
},
|
|
302
|
-
catch: error => new Error(`Connection failed: ${error instanceof Error ? error.message : String(error)}`),
|
|
253
|
+
catch: (error) => new Error(`Connection failed: ${error instanceof Error ? error.message : String(error)}`),
|
|
303
254
|
});
|
|
304
255
|
const generateConfigContent = (answers) => {
|
|
305
|
-
//
|
|
306
|
-
const selectedPlugins = pipe(answers.plugins, Array.filterMap(value => {
|
|
256
|
+
// Get unique plugin imports (dedupe e.g., kysely-types + kysely-queries -> single kysely import)
|
|
257
|
+
const selectedPlugins = pipe(answers.plugins, Array.filterMap((value) => {
|
|
307
258
|
const info = getPluginInfo(value);
|
|
308
259
|
return info ? Option.some(info) : Option.none();
|
|
309
260
|
}));
|
|
310
|
-
//
|
|
311
|
-
const
|
|
312
|
-
const
|
|
313
|
-
// Build
|
|
314
|
-
const importDecl = conjure.
|
|
315
|
-
// Build
|
|
261
|
+
// Deduplicate by import name (keep first occurrence)
|
|
262
|
+
const uniqueImports = pipe(selectedPlugins, Array.dedupeWith((a, b) => a.importName === b.importName));
|
|
263
|
+
const allImportNames = ["defineConfig", ...uniqueImports.map((p) => p.importName)];
|
|
264
|
+
// Build import declaration: import { defineConfig, plugin1, plugin2 } from "@danielfgray/pg-sourcerer"
|
|
265
|
+
const importDecl = conjure.import.named("@danielfgray/pg-sourcerer", ...allImportNames);
|
|
266
|
+
// Build config object
|
|
316
267
|
let configObj = conjure.obj();
|
|
268
|
+
// connectionString - either env ref or literal
|
|
317
269
|
if (answers.isEnvRef) {
|
|
318
|
-
// Generate: connectionString: process.env.DATABASE_URL!
|
|
319
270
|
const envKey = answers.connectionConfigValue.replace("process.env.", "");
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const envAccessWithAssertion = conjure.b.tsNonNullExpression(envAccess);
|
|
323
|
-
configObj = configObj.prop("connectionString", envAccessWithAssertion);
|
|
271
|
+
// process.env.VAR!
|
|
272
|
+
configObj = configObj.prop("connectionString", conjure.nonNull(conjure.id("process").prop("env").prop(envKey).build()));
|
|
324
273
|
}
|
|
325
274
|
else {
|
|
326
275
|
configObj = configObj.prop("connectionString", conjure.str(answers.connectionConfigValue));
|
|
327
276
|
}
|
|
328
|
-
//
|
|
277
|
+
// role (optional)
|
|
329
278
|
if (answers.role) {
|
|
330
279
|
configObj = configObj.prop("role", conjure.str(answers.role));
|
|
331
280
|
}
|
|
332
|
-
//
|
|
281
|
+
// schemas (only if not default ["public"])
|
|
333
282
|
if (answers.schemas.length !== 1 || answers.schemas[0] !== "public") {
|
|
334
|
-
|
|
335
|
-
configObj = configObj.prop("schemas", schemasArr.build());
|
|
283
|
+
configObj = configObj.prop("schemas", conjure.arr(...answers.schemas.map((s) => conjure.str(s))).build());
|
|
336
284
|
}
|
|
337
|
-
//
|
|
285
|
+
// outputDir (only if not default)
|
|
338
286
|
if (answers.outputDir !== "src/generated") {
|
|
339
287
|
configObj = configObj.prop("outputDir", conjure.str(answers.outputDir));
|
|
340
288
|
}
|
|
341
|
-
//
|
|
289
|
+
// formatter (optional)
|
|
342
290
|
if (answers.formatter.trim()) {
|
|
343
291
|
configObj = configObj.prop("formatter", conjure.str(answers.formatter.trim()));
|
|
344
292
|
}
|
|
345
|
-
//
|
|
346
|
-
const pluginCalls =
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
// Build the export default statement
|
|
293
|
+
// plugins array: [plugin1(), plugin2(), ...]
|
|
294
|
+
const pluginCalls = uniqueImports.map((p) => conjure.id(p.importName).call().build());
|
|
295
|
+
configObj = configObj.prop("plugins", conjure.arr(...pluginCalls).build());
|
|
296
|
+
// Build: export default defineConfig({ ... })
|
|
350
297
|
const defineConfigCall = conjure.id("defineConfig").call([configObj.build()]).build();
|
|
351
298
|
const exportDefault = conjure.export.default(defineConfigCall);
|
|
352
|
-
//
|
|
299
|
+
// Create program and print
|
|
353
300
|
const program = conjure.program(importDecl, exportDefault);
|
|
354
|
-
return
|
|
301
|
+
return conjure.print(program) + "\n";
|
|
355
302
|
};
|
|
356
|
-
// ============================================================================
|
|
357
|
-
// Main Init Effect
|
|
358
|
-
// ============================================================================
|
|
359
303
|
const CONFIG_FILENAME = "pgsourcerer.config.ts";
|
|
360
304
|
export const runInit = Effect.gen(function* () {
|
|
361
305
|
const fs = yield* FileSystem.FileSystem;
|
|
362
306
|
const configPath = `${process.cwd()}/${CONFIG_FILENAME}`;
|
|
363
|
-
// Check if config already exists
|
|
364
307
|
const exists = yield* fs.exists(configPath);
|
|
365
308
|
if (exists) {
|
|
366
309
|
yield* Console.error(`\n✗ ${CONFIG_FILENAME} already exists`);
|
|
@@ -368,20 +311,14 @@ export const runInit = Effect.gen(function* () {
|
|
|
368
311
|
return yield* Effect.fail(new Error("Config already exists"));
|
|
369
312
|
}
|
|
370
313
|
yield* Console.log("\n🔧 pg-sourcerer config generator\n");
|
|
371
|
-
// Collect answers - connection string may be detected from env
|
|
372
314
|
const { connectionString, configValue, isEnvRef } = yield* getConnectionString;
|
|
373
|
-
// Introspect to discover schemas
|
|
374
315
|
yield* Console.log("Introspecting database...");
|
|
375
|
-
const introspection = yield* introspectDatabase({ connectionString }).pipe(Effect.catchAll(e => {
|
|
376
|
-
// Log error but continue with empty introspection for fallback text prompt
|
|
377
|
-
return Console.error(`Warning: ${e.message}`).pipe(Effect.andThen(Effect.succeed({ classes: [] })));
|
|
378
|
-
}));
|
|
316
|
+
const introspection = yield* introspectDatabase({ connectionString }).pipe(Effect.catchAll((e) => Console.error(`Warning: ${e.message}`).pipe(Effect.andThen(Effect.succeed({ classes: [] })))));
|
|
379
317
|
const role = yield* makeRolePrompt();
|
|
380
318
|
const schemas = yield* makeSchemasPrompt(introspection);
|
|
381
319
|
const outputDir = yield* makeOutputDirPrompt();
|
|
382
320
|
const plugins = yield* makePluginsPrompt();
|
|
383
321
|
const formatter = yield* makeFormatterPrompt();
|
|
384
|
-
// Validate at least one plugin selected
|
|
385
322
|
if (plugins.length === 0) {
|
|
386
323
|
yield* Console.error("✗ At least one plugin must be selected");
|
|
387
324
|
return yield* Effect.fail(new Error("No plugins selected"));
|
|
@@ -396,7 +333,6 @@ export const runInit = Effect.gen(function* () {
|
|
|
396
333
|
plugins,
|
|
397
334
|
formatter,
|
|
398
335
|
};
|
|
399
|
-
// Generate and write config
|
|
400
336
|
const configContent = generateConfigContent(answers);
|
|
401
337
|
yield* fs.writeFileString(configPath, configContent);
|
|
402
338
|
yield* Console.log(`\n✓ Created ${CONFIG_FILENAME}`);
|