@apso/cli 0.8.6 → 0.10.1

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.
Files changed (91) hide show
  1. package/README.md +221 -1653
  2. package/dist/commands/config.d.ts +13 -0
  3. package/dist/commands/config.js +114 -0
  4. package/dist/commands/deploy.d.ts +11 -0
  5. package/dist/commands/deploy.js +141 -0
  6. package/dist/commands/dev.d.ts +15 -0
  7. package/dist/commands/dev.js +95 -0
  8. package/dist/commands/generate.d.ts +12 -0
  9. package/dist/commands/generate.js +179 -0
  10. package/dist/commands/init.d.ts +16 -0
  11. package/dist/commands/init.js +313 -0
  12. package/dist/commands/link.d.ts +11 -0
  13. package/dist/commands/link.js +139 -0
  14. package/dist/commands/login.d.ts +22 -0
  15. package/dist/commands/login.js +345 -0
  16. package/dist/commands/logout.d.ts +9 -0
  17. package/dist/commands/logout.js +38 -0
  18. package/dist/commands/logs.d.ts +10 -0
  19. package/dist/commands/logs.js +64 -0
  20. package/dist/commands/mcp/serve.d.ts +11 -0
  21. package/dist/commands/mcp/serve.js +818 -0
  22. package/dist/commands/migrate.d.ts +11 -0
  23. package/dist/commands/migrate.js +137 -0
  24. package/dist/commands/open.d.ts +10 -0
  25. package/dist/commands/open.js +79 -0
  26. package/dist/commands/projects.d.ts +10 -0
  27. package/dist/commands/projects.js +106 -0
  28. package/dist/commands/schema/diff.d.ts +7 -0
  29. package/dist/commands/schema/diff.js +63 -0
  30. package/dist/commands/schema/pull.d.ts +9 -0
  31. package/dist/commands/schema/pull.js +81 -0
  32. package/dist/commands/schema/push.d.ts +9 -0
  33. package/dist/commands/schema/push.js +97 -0
  34. package/dist/commands/schema/validate.d.ts +9 -0
  35. package/dist/commands/schema/validate.js +90 -0
  36. package/dist/commands/server/new.d.ts +2 -19
  37. package/dist/commands/server/new.js +6 -192
  38. package/dist/commands/server/scaffold.d.ts +2 -25
  39. package/dist/commands/server/scaffold.js +6 -312
  40. package/dist/commands/status.d.ts +7 -0
  41. package/dist/commands/status.js +53 -0
  42. package/dist/commands/unlink.d.ts +9 -0
  43. package/dist/commands/unlink.js +47 -0
  44. package/dist/commands/whoami.d.ts +10 -0
  45. package/dist/commands/whoami.js +97 -0
  46. package/dist/lib/api/client.js +1 -1
  47. package/dist/lib/api/services.js +3 -3
  48. package/dist/lib/api/types.d.ts +9 -2
  49. package/dist/lib/apsorc-parser.d.ts +0 -19
  50. package/dist/lib/apsorc-parser.js +2 -73
  51. package/dist/lib/guards.d.ts +3 -20
  52. package/dist/lib/guards.js +1 -113
  53. package/dist/lib/index.d.ts +1 -9
  54. package/dist/lib/index.js +1 -18
  55. package/dist/lib/migrate/entity-generator.d.ts +14 -0
  56. package/dist/lib/migrate/entity-generator.js +7 -0
  57. package/dist/lib/migrate/sandbox.d.ts +42 -0
  58. package/dist/lib/migrate/sandbox.js +337 -0
  59. package/dist/lib/migrate/snapshot.d.ts +80 -0
  60. package/dist/lib/migrate/snapshot.js +100 -0
  61. package/dist/lib/templates/python/models/model-col-datetime.eta +1 -1
  62. package/dist/lib/templates/python/models/model-col-string.eta +1 -1
  63. package/dist/lib/templates/python/models/model-col-text.eta +1 -1
  64. package/dist/lib/templates/python/models/model-col-varchar.eta +1 -1
  65. package/dist/lib/utils/field.d.ts +12 -0
  66. package/dist/lib/utils/field.js +80 -1
  67. package/dist/lib/utils/schema-convert.d.ts +71 -0
  68. package/dist/lib/utils/schema-convert.js +169 -0
  69. package/dist/lib/utils/spinner.d.ts +19 -0
  70. package/dist/lib/utils/spinner.js +87 -0
  71. package/dist/lib/utils/template.d.ts +12 -0
  72. package/dist/lib/utils/template.js +49 -0
  73. package/npm-shrinkwrap.json +18118 -0
  74. package/oclif.manifest.json +547 -41
  75. package/package.json +26 -5
  76. package/dist/lib/controller.d.ts +0 -10
  77. package/dist/lib/controller.js +0 -99
  78. package/dist/lib/dto.d.ts +0 -16
  79. package/dist/lib/dto.js +0 -92
  80. package/dist/lib/entity.d.ts +0 -19
  81. package/dist/lib/entity.js +0 -56
  82. package/dist/lib/enums.d.ts +0 -6
  83. package/dist/lib/enums.js +0 -28
  84. package/dist/lib/gql-dto.d.ts +0 -3
  85. package/dist/lib/gql-dto.js +0 -39
  86. package/dist/lib/index-module.d.ts +0 -13
  87. package/dist/lib/index-module.js +0 -26
  88. package/dist/lib/module.d.ts +0 -13
  89. package/dist/lib/module.js +0 -42
  90. package/dist/lib/service.d.ts +0 -2
  91. package/dist/lib/service.js +0 -61
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadConfig = exports.findConfigPath = exports.parseApsorc = exports.parseApsorcV2 = exports.parseApsorcV1 = exports.ApiType = void 0;
3
+ exports.findConfigPath = exports.parseApsorc = exports.parseApsorcV2 = exports.parseApsorcV1 = exports.ApiType = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const fs = tslib_1.__importStar(require("fs"));
6
6
  const path = tslib_1.__importStar(require("path"));
@@ -105,7 +105,6 @@ exports.parseApsorc = parseApsorc;
105
105
  */
106
106
  const findConfigPath = () => {
107
107
  let currentDir = process.cwd();
108
- // Search upwards
109
108
  while (currentDir !== path.parse(currentDir).root) {
110
109
  const configPath = path.join(currentDir, ".apsorc");
111
110
  if (fs.existsSync(configPath)) {
@@ -113,80 +112,10 @@ const findConfigPath = () => {
113
112
  }
114
113
  currentDir = path.dirname(currentDir);
115
114
  }
116
- // Check root directory as well
117
115
  const rootConfigPath = path.join(currentDir, ".apsorc");
118
116
  if (fs.existsSync(rootConfigPath)) {
119
117
  return rootConfigPath;
120
118
  }
121
- return null; // Not found
119
+ return null;
122
120
  };
123
121
  exports.findConfigPath = findConfigPath;
124
- /**
125
- * Loads, validates, and potentially migrates the .apsorc configuration.
126
- * Uses the `rc` library to find and load the .apsorc file.
127
- * Detects config version (V1 or V2) and migrates V1 to V2 if necessary.
128
- * Performs basic validation on the final V2 structure.
129
- * @param appName The name of the application (used by `rc`). Defaults to 'apso'.
130
- * @param defaults Default configuration values (used by `rc`).
131
- * @returns The unified configuration (entities, relationships, rootFolder).
132
- * @throws Error if the config file cannot be found, is invalid, or migration fails.
133
- */
134
- const loadConfig = (appName = "apso", defaults = {}) => {
135
- // Use rc to find and load the configuration file (.apsorc)
136
- const configData = (0, rc_1.default)(appName, defaults);
137
- const rootFolder = configData.rootFolder || "src"; // Get rootFolder early
138
- // Check if rc found and loaded the config
139
- // rc returns an object with default keys if nothing is found,
140
- // so check for more than just default keys or if configData.config exists
141
- const hasMeaningfulConfig = configData &&
142
- Object.keys(configData).some((key) => !Object.prototype.hasOwnProperty.call(defaults, key) && key !== "_") &&
143
- configData.configs &&
144
- configData.configs.length > 0;
145
- if (!hasMeaningfulConfig) {
146
- // If rc didn't find it, try our manual search as a fallback
147
- const foundPath = (0, exports.findConfigPath)();
148
- // Use ternary to satisfy unicorn/prefer-ternary rule
149
- throw foundPath
150
- ? new Error(`Configuration file found at: ${foundPath}, but failed to parse. Ensure it is valid JSON or INI.`)
151
- : new Error(".apsorc configuration file not found in the current directory or any parent directory.");
152
- }
153
- // Determine version and parse accordingly using existing functions
154
- const version = configData.version || 1; // Default to 1 if undefined
155
- let parsedData;
156
- // Create an object matching ApsorcType structure from rc data
157
- const apsorcInput = {
158
- version: version,
159
- rootFolder: rootFolder,
160
- entities: configData.entities || [],
161
- apiType: configData.apiType || ApiType.Rest,
162
- relationships: configData.relationships || [],
163
- };
164
- if (version === 1) {
165
- // Pass the correctly structured object
166
- parsedData = (0, exports.parseApsorcV1)(apsorcInput);
167
- }
168
- else if (version === 2 && Array.isArray(configData.relationships)) {
169
- // Pass the correctly structured object
170
- parsedData = (0, exports.parseApsorcV2)(apsorcInput);
171
- }
172
- else {
173
- throw new Error("Invalid .apsorc format. Could not determine configuration version or structure.");
174
- }
175
- // Basic validation on the result of parsing
176
- if (!parsedData.entities || !Array.isArray(parsedData.entities)) {
177
- throw new Error("Invalid config: 'entities' array is missing or invalid after parsing.");
178
- }
179
- if (!rootFolder || typeof rootFolder !== "string") {
180
- throw new Error("Invalid config: 'rootFolder' string is missing or invalid.");
181
- }
182
- // Relationships are implicitly validated by parseRelationships/parseV1Relationships
183
- return {
184
- entities: parsedData.entities,
185
- // Extract relationships from the relationshipMap keys/values if needed,
186
- // or adjust UnifiedConfig. For now, returning empty array as placeholder.
187
- // The relationshipMap is the primary output needed by downstream code.
188
- relationships: [],
189
- rootFolder: rootFolder,
190
- };
191
- };
192
- exports.loadConfig = loadConfig;
@@ -1,8 +1,8 @@
1
- import { Entity, AuthConfig } from "./types";
1
+ import { Entity } from "./types";
2
2
  /**
3
3
  * Represents a scope field configuration for template rendering
4
4
  */
5
- interface ScopeFieldConfig {
5
+ export interface ScopeFieldConfig {
6
6
  field: string;
7
7
  contextKey: string;
8
8
  direct: boolean;
@@ -11,7 +11,7 @@ interface ScopeFieldConfig {
11
11
  /**
12
12
  * Represents a scoped entity configuration for template rendering
13
13
  */
14
- interface ScopedEntityConfig {
14
+ export interface ScopedEntityConfig {
15
15
  name: string;
16
16
  routeName: string;
17
17
  repoName: string;
@@ -22,26 +22,9 @@ interface ScopedEntityConfig {
22
22
  }
23
23
  /**
24
24
  * Extracts scoped entity configurations from all entities.
25
- *
26
- * @param entities Array of all entities from the parsed .apsorc.
27
- * @returns Array of scoped entity configurations for entities that have scopeBy defined.
28
25
  */
29
26
  export declare function getScopedEntities(entities: Entity[]): ScopedEntityConfig[];
30
27
  /**
31
28
  * Checks if any entities have scopeBy configured.
32
- *
33
- * @param entities Array of all entities from the parsed .apsorc.
34
- * @returns True if at least one entity has scopeBy defined.
35
29
  */
36
30
  export declare function hasScopedEntities(entities: Entity[]): boolean;
37
- /**
38
- * Generates the guards module directory and files.
39
- * Creates auth.guard.ts, scope.guard.ts, guards.module.ts, and index.ts in the guards directory.
40
- *
41
- * @param rootPath The root path of the generated source (e.g., 'src').
42
- * @param entities All entities from the parsed .apsorc.
43
- * @param auth Optional auth configuration from .apsorc.
44
- * @returns {Promise<void>} A promise that resolves when the guard files are created.
45
- */
46
- export declare const createGuards: (rootPath: string, entities: Entity[], auth?: AuthConfig) => Promise<void>;
47
- export {};
@@ -1,12 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createGuards = exports.hasScopedEntities = exports.getScopedEntities = void 0;
3
+ exports.hasScopedEntities = exports.getScopedEntities = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const Eta = tslib_1.__importStar(require("eta"));
6
- const path = tslib_1.__importStar(require("path"));
7
- const fs = tslib_1.__importStar(require("fs"));
8
- const file_system_1 = require("./utils/file-system");
9
- const types_1 = require("./types");
10
5
  const pluralize_1 = tslib_1.__importDefault(require("pluralize"));
11
6
  /**
12
7
  * Default scope options when not specified
@@ -18,17 +13,12 @@ const DEFAULT_SCOPE_OPTIONS = {
18
13
  };
19
14
  /**
20
15
  * Parses scopeBy configuration and returns structured scope fields.
21
- *
22
- * @param scopeBy The scope configuration - either a single field/path string or an array of them.
23
- * @returns An array of scope field configurations.
24
16
  */
25
17
  function parseScopeBy(scopeBy) {
26
18
  const scopes = Array.isArray(scopeBy) ? scopeBy : [scopeBy];
27
19
  return scopes.map((scope) => {
28
20
  const isDirect = !scope.includes(".");
29
21
  const field = isDirect ? scope : scope.split(".")[0];
30
- // For direct fields, contextKey is the same as field
31
- // For nested paths like 'task.workspaceId', we extract 'workspaceId' as contextKey
32
22
  const contextKey = isDirect ? scope : scope.split(".").pop();
33
23
  return {
34
24
  field,
@@ -38,32 +28,15 @@ function parseScopeBy(scopeBy) {
38
28
  };
39
29
  });
40
30
  }
41
- /**
42
- * Converts entity name to lowercase pluralized route name.
43
- * e.g., "Project" -> "projects", "DiscoverySession" -> "discoverysessions"
44
- *
45
- * @param entityName The entity name in PascalCase.
46
- * @returns The lowercase pluralized route name.
47
- */
48
31
  function toRouteName(entityName) {
49
32
  return (0, pluralize_1.default)(entityName).toLowerCase();
50
33
  }
51
- /**
52
- * Converts entity name to repository variable name.
53
- * e.g., "Project" -> "projectRepository", "DiscoverySession" -> "discoverySessionRepository"
54
- *
55
- * @param entityName The entity name in PascalCase.
56
- * @returns The camelCase repository variable name.
57
- */
58
34
  function toRepoName(entityName) {
59
35
  const camelCase = entityName.charAt(0).toLowerCase() + entityName.slice(1);
60
36
  return `${camelCase}Repository`;
61
37
  }
62
38
  /**
63
39
  * Extracts scoped entity configurations from all entities.
64
- *
65
- * @param entities Array of all entities from the parsed .apsorc.
66
- * @returns Array of scoped entity configurations for entities that have scopeBy defined.
67
40
  */
68
41
  function getScopedEntities(entities) {
69
42
  return entities
@@ -84,93 +57,8 @@ function getScopedEntities(entities) {
84
57
  exports.getScopedEntities = getScopedEntities;
85
58
  /**
86
59
  * Checks if any entities have scopeBy configured.
87
- *
88
- * @param entities Array of all entities from the parsed .apsorc.
89
- * @returns True if at least one entity has scopeBy defined.
90
60
  */
91
61
  function hasScopedEntities(entities) {
92
62
  return entities.some((entity) => entity.scopeBy);
93
63
  }
94
64
  exports.hasScopedEntities = hasScopedEntities;
95
- /**
96
- * Normalizes auth config by applying defaults for DB session providers
97
- * @param {AuthConfig | undefined} auth - The auth configuration to normalize
98
- * @returns {DbSessionAuthConfig | undefined} The normalized auth config or undefined
99
- */
100
- function normalizeAuthConfig(auth) {
101
- if (!auth)
102
- return undefined;
103
- if ((0, types_1.isDbSessionAuth)(auth)) {
104
- return {
105
- ...types_1.DB_SESSION_AUTH_DEFAULTS,
106
- ...auth,
107
- };
108
- }
109
- // For now, only DB session providers are supported
110
- // JWT providers will be added later
111
- console.log(`[apso] Auth provider '${auth.provider}' is not yet supported, skipping auth guard generation`);
112
- return undefined;
113
- }
114
- /**
115
- * Generates the guards module directory and files.
116
- * Creates auth.guard.ts, scope.guard.ts, guards.module.ts, and index.ts in the guards directory.
117
- *
118
- * @param rootPath The root path of the generated source (e.g., 'src').
119
- * @param entities All entities from the parsed .apsorc.
120
- * @param auth Optional auth configuration from .apsorc.
121
- * @returns {Promise<void>} A promise that resolves when the guard files are created.
122
- */
123
- const createGuards = async (rootPath, entities, auth) => {
124
- const hasScopes = hasScopedEntities(entities);
125
- const normalizedAuth = normalizeAuthConfig(auth);
126
- // Only generate guards if there are scoped entities OR auth config
127
- if (!hasScopes && !normalizedAuth) {
128
- console.log("[apso] No scopeBy or auth configurations found, skipping guards generation");
129
- return;
130
- }
131
- const guardsDir = path.join(rootPath, "autogen", "guards");
132
- // Ensure guards directory exists
133
- if (!fs.existsSync(guardsDir)) {
134
- fs.mkdirSync(guardsDir, { recursive: true });
135
- }
136
- const scopedEntities = getScopedEntities(entities);
137
- // Common template data
138
- const templateData = {
139
- scopedEntities,
140
- authConfig: normalizedAuth,
141
- generatedAt: new Date().toISOString(),
142
- generatedBy: "Apso CLI",
143
- };
144
- // Generate auth.guard.ts if auth is configured
145
- if (normalizedAuth) {
146
- const authGuardPath = path.join(guardsDir, "auth.guard.ts");
147
- const authGuardContent = await Eta.renderFileAsync("./guards/auth.guard.eta", templateData);
148
- await (0, file_system_1.createFile)(authGuardPath, authGuardContent);
149
- console.log(`[apso] Generated ${authGuardPath}`);
150
- }
151
- // Generate scope.guard.ts if there are scoped entities
152
- if (hasScopes) {
153
- const scopeGuardPath = path.join(guardsDir, "scope.guard.ts");
154
- const scopeGuardContent = await Eta.renderFileAsync("./guards/scope.guard.eta", templateData);
155
- await (0, file_system_1.createFile)(scopeGuardPath, scopeGuardContent);
156
- console.log(`[apso] Generated ${scopeGuardPath}`);
157
- }
158
- // Generate guards.module.ts
159
- const guardsModulePath = path.join(guardsDir, "guards.module.ts");
160
- const guardsModuleContent = await Eta.renderFileAsync("./guards/guards.module.eta", templateData);
161
- await (0, file_system_1.createFile)(guardsModulePath, guardsModuleContent);
162
- console.log(`[apso] Generated ${guardsModulePath}`);
163
- // Generate index.ts
164
- const indexPath = path.join(guardsDir, "index.ts");
165
- const indexContent = await Eta.renderFileAsync("./guards/index.eta", templateData);
166
- await (0, file_system_1.createFile)(indexPath, indexContent);
167
- console.log(`[apso] Generated ${indexPath}`);
168
- // Summary
169
- const parts = [];
170
- if (normalizedAuth)
171
- parts.push(`auth (${normalizedAuth.provider})`);
172
- if (scopedEntities.length > 0)
173
- parts.push(`${scopedEntities.length} scoped entities`);
174
- console.log(`[apso] Generated guards for ${parts.join(" + ")}`);
175
- };
176
- exports.createGuards = createGuards;
@@ -1,13 +1,5 @@
1
1
  export { Entity, RelationshipMap } from "./types";
2
2
  export { parseApsorc } from "./apsorc-parser";
3
- export { createEntity } from "./entity";
4
- export { createController } from "./controller";
5
- export { createService } from "./service";
6
- export { createModule } from "./module";
7
- export { createIndexAppModule } from "./index-module";
8
- export { createDto } from "./dto";
9
- export { createEnums } from "./enums";
10
- export { createGqlDTO } from "./gql-dto";
11
- export { createGuards, hasScopedEntities, getScopedEntities } from "./guards";
3
+ export { hasScopedEntities, getScopedEntities } from "./guards";
12
4
  export { BaseGenerator, TypeScriptGenerator, createGenerator, isLanguageSupported, getSupportedLanguages, getImplementedLanguages, } from "./generators";
13
5
  export type { TargetLanguage, GeneratedFile, ValidationResult, GeneratorConfig, LanguageGenerator, } from "./types";
package/dist/lib/index.js CHANGED
@@ -1,26 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getImplementedLanguages = exports.getSupportedLanguages = exports.isLanguageSupported = exports.createGenerator = exports.TypeScriptGenerator = exports.BaseGenerator = exports.getScopedEntities = exports.hasScopedEntities = exports.createGuards = exports.createGqlDTO = exports.createEnums = exports.createDto = exports.createIndexAppModule = exports.createModule = exports.createService = exports.createController = exports.createEntity = exports.parseApsorc = void 0;
3
+ exports.getImplementedLanguages = exports.getSupportedLanguages = exports.isLanguageSupported = exports.createGenerator = exports.TypeScriptGenerator = exports.BaseGenerator = exports.getScopedEntities = exports.hasScopedEntities = exports.parseApsorc = void 0;
4
4
  var apsorc_parser_1 = require("./apsorc-parser");
5
5
  Object.defineProperty(exports, "parseApsorc", { enumerable: true, get: function () { return apsorc_parser_1.parseApsorc; } });
6
- var entity_1 = require("./entity");
7
- Object.defineProperty(exports, "createEntity", { enumerable: true, get: function () { return entity_1.createEntity; } });
8
- var controller_1 = require("./controller");
9
- Object.defineProperty(exports, "createController", { enumerable: true, get: function () { return controller_1.createController; } });
10
- var service_1 = require("./service");
11
- Object.defineProperty(exports, "createService", { enumerable: true, get: function () { return service_1.createService; } });
12
- var module_1 = require("./module");
13
- Object.defineProperty(exports, "createModule", { enumerable: true, get: function () { return module_1.createModule; } });
14
- var index_module_1 = require("./index-module");
15
- Object.defineProperty(exports, "createIndexAppModule", { enumerable: true, get: function () { return index_module_1.createIndexAppModule; } });
16
- var dto_1 = require("./dto");
17
- Object.defineProperty(exports, "createDto", { enumerable: true, get: function () { return dto_1.createDto; } });
18
- var enums_1 = require("./enums");
19
- Object.defineProperty(exports, "createEnums", { enumerable: true, get: function () { return enums_1.createEnums; } });
20
- var gql_dto_1 = require("./gql-dto");
21
- Object.defineProperty(exports, "createGqlDTO", { enumerable: true, get: function () { return gql_dto_1.createGqlDTO; } });
22
6
  var guards_1 = require("./guards");
23
- Object.defineProperty(exports, "createGuards", { enumerable: true, get: function () { return guards_1.createGuards; } });
24
7
  Object.defineProperty(exports, "hasScopedEntities", { enumerable: true, get: function () { return guards_1.hasScopedEntities; } });
25
8
  Object.defineProperty(exports, "getScopedEntities", { enumerable: true, get: function () { return guards_1.getScopedEntities; } });
26
9
  // Generator exports
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Sandbox Entity Generator Types
3
+ *
4
+ * Provides the input type for the migration sandbox.
5
+ */
6
+ import { Entity } from "../types/entity";
7
+ import { RelationshipMap } from "../types/relationship";
8
+ /**
9
+ * Subset of ParsedApsorc needed for migration sandbox operations.
10
+ */
11
+ export interface EntityGeneratorInput {
12
+ entities: Entity[];
13
+ relationshipMap: RelationshipMap;
14
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * Sandbox Entity Generator Types
4
+ *
5
+ * Provides the input type for the migration sandbox.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Migration Sandbox
3
+ *
4
+ * The core migration testing engine. Uses PGlite (in-process Postgres) to:
5
+ * 1. Establish a baseline schema from the previous snapshot
6
+ * 2. Compute the diff against the current schema
7
+ * 3. Generate and test migration SQL locally
8
+ *
9
+ * This validates migrations before anything touches a remote database.
10
+ */
11
+ import { EntityGeneratorInput } from "./entity-generator";
12
+ /**
13
+ * Result of a migration sandbox run.
14
+ */
15
+ export interface MigrationResult {
16
+ /** Whether the migration was needed (schema changed) */
17
+ needed: boolean;
18
+ /** Whether the migration executed without errors */
19
+ success: boolean;
20
+ /** Generated SQL statements (up direction) */
21
+ upSql: string[];
22
+ /** Generated SQL statements (down direction) */
23
+ downSql: string[];
24
+ /** Error message if migration failed */
25
+ error?: string;
26
+ }
27
+ /**
28
+ * Run the migration sandbox: detect changes, generate SQL, test execution.
29
+ *
30
+ * Uses PGlite's singleton pattern: all DataSources within a single
31
+ * runMigrationSandbox call share the same in-process Postgres instance.
32
+ * We reset the singleton at the start of each run for isolation.
33
+ */
34
+ export declare function runMigrationSandbox(current: EntityGeneratorInput, projectDir?: string): Promise<MigrationResult>;
35
+ /**
36
+ * Apply a successful migration: update the snapshot to current state.
37
+ */
38
+ export declare function applyMigration(current: EntityGeneratorInput, projectDir?: string): void;
39
+ /**
40
+ * Reset the sandbox: remove snapshot and PGlite data.
41
+ */
42
+ export declare function resetSandbox(projectDir?: string): void;