@friggframework/core 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.35ee143.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/CHANGELOG.md +67 -66
- package/CLAUDE.md +124 -148
- package/README.md +130 -165
- package/admin-scripts/index.js +16 -30
- package/admin-scripts/repositories/{admin-api-key-repository-documentdb.js → admin-process-repository-documentdb.js} +5 -5
- package/admin-scripts/repositories/{admin-api-key-repository-factory.js → admin-process-repository-factory.js} +15 -19
- package/admin-scripts/repositories/admin-process-repository-interface.js +150 -0
- package/admin-scripts/repositories/admin-process-repository-mongo.js +213 -0
- package/admin-scripts/repositories/admin-process-repository-postgres.js +251 -0
- package/admin-scripts/repositories/script-schedule-repository-factory.js +2 -6
- package/admin-scripts/repositories/script-schedule-repository-interface.js +14 -36
- package/admin-scripts/repositories/script-schedule-repository-mongo.js +13 -25
- package/admin-scripts/repositories/script-schedule-repository-postgres.js +13 -25
- package/application/commands/admin-script-commands.js +102 -266
- package/application/commands/integration-commands.js +6 -12
- package/application/index.js +3 -1
- package/assertions/get.js +4 -1
- package/associations/association.js +57 -59
- package/associations/model.js +41 -41
- package/core/CLAUDE.md +156 -222
- package/core/Worker.js +1 -5
- package/credential/repositories/credential-repository-documentdb.js +1 -71
- package/credential/repositories/credential-repository-interface.js +2 -8
- package/credential/repositories/credential-repository-mongo.js +4 -45
- package/credential/repositories/credential-repository-postgres.js +3 -44
- package/credential/repositories/credential-repository.js +4 -6
- package/credential/use-cases/get-credential-for-user.js +3 -21
- package/credential/use-cases/update-authentication-status.js +2 -5
- package/database/MONGODB_TRANSACTION_FIX.md +52 -72
- package/database/adapters/lambda-invoker.js +7 -8
- package/database/config.js +13 -15
- package/database/documentdb-encryption-service.js +13 -29
- package/database/documentdb-utils.js +12 -21
- package/database/encryption/README.md +36 -53
- package/database/encryption/encryption-schema-registry.js +9 -21
- package/database/encryption/field-encryption-service.js +4 -15
- package/database/encryption/logger.js +2 -3
- package/database/encryption/prisma-encryption-extension.js +8 -5
- package/database/index.js +2 -4
- package/database/models/IndividualUser.js +15 -15
- package/database/models/OrganizationUser.js +4 -6
- package/database/models/UserModel.js +2 -2
- package/database/models/WebsocketConnection.js +1 -4
- package/database/mongoose.js +2 -2
- package/database/prisma.js +14 -22
- package/database/repositories/health-check-repository-documentdb.js +7 -22
- package/database/repositories/health-check-repository-factory.js +3 -9
- package/database/repositories/health-check-repository-interface.js +5 -15
- package/database/repositories/health-check-repository-mongodb.js +6 -9
- package/database/repositories/health-check-repository-postgres.js +1 -1
- package/database/repositories/migration-status-repository-s3.js +5 -10
- package/database/use-cases/check-database-health-use-case.js +2 -3
- package/database/use-cases/check-database-state-use-case.js +7 -9
- package/database/use-cases/get-database-state-via-worker-use-case.js +12 -15
- package/database/use-cases/get-migration-status-use-case.js +2 -4
- package/database/use-cases/run-database-migration-use-case.js +9 -41
- package/database/use-cases/test-encryption-use-case.js +5 -4
- package/database/use-cases/trigger-database-migration-use-case.js +8 -9
- package/database/utils/mongodb-collection-utils.js +3 -11
- package/database/utils/mongodb-schema-init.js +4 -10
- package/database/utils/prisma-runner.js +74 -144
- package/database/utils/prisma-schema-parser.js +2 -2
- package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +80 -135
- package/encrypt/Cryptor.js +2 -8
- package/errors/fetch-error.js +1 -1
- package/generated/prisma-mongodb/edge.js +16 -59
- package/generated/prisma-mongodb/index-browser.js +12 -62
- package/generated/prisma-mongodb/index.d.ts +4850 -8136
- package/generated/prisma-mongodb/index.js +16 -59
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +33 -75
- package/generated/prisma-mongodb/wasm.js +16 -59
- package/generated/prisma-postgresql/edge.js +15 -59
- package/generated/prisma-postgresql/index-browser.js +11 -62
- package/generated/prisma-postgresql/index.d.ts +5963 -8930
- package/generated/prisma-postgresql/index.js +15 -59
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +33 -73
- package/generated/prisma-postgresql/wasm.js +15 -59
- package/handlers/WEBHOOKS.md +81 -104
- package/handlers/app-definition-loader.js +1 -1
- package/handlers/app-handler-helpers.js +2 -14
- package/handlers/backend-utils.js +1 -0
- package/handlers/database-migration-handler.js +45 -64
- package/handlers/middleware/admin-auth.js +53 -0
- package/handlers/routers/HEALTHCHECK.md +135 -170
- package/handlers/routers/auth.js +2 -23
- package/handlers/routers/db-migration.handler.js +3 -2
- package/handlers/routers/db-migration.js +33 -69
- package/handlers/routers/health.js +8 -23
- package/handlers/routers/integration-defined-routers.js +4 -4
- package/handlers/routers/integration-webhook-routers.js +7 -17
- package/handlers/routers/websocket.js +3 -9
- package/handlers/use-cases/check-integrations-health-use-case.js +6 -13
- package/handlers/workers/db-migration.js +26 -54
- package/index.js +9 -5
- package/integrations/WEBHOOK-QUICKSTART.md +14 -21
- package/integrations/index.js +0 -4
- package/integrations/integration-base.js +6 -9
- package/integrations/integration-router.js +146 -1817
- package/integrations/options.js +20 -47
- package/integrations/repositories/integration-repository-documentdb.js +24 -53
- package/integrations/repositories/integration-repository-factory.js +2 -6
- package/integrations/repositories/integration-repository-interface.js +9 -27
- package/integrations/repositories/integration-repository-postgres.js +3 -3
- package/integrations/repositories/process-repository-factory.js +1 -0
- package/integrations/repositories/process-repository-interface.js +5 -9
- package/integrations/repositories/process-repository-mongo.js +3 -7
- package/integrations/repositories/process-repository-postgres.js +2 -2
- package/integrations/tests/doubles/config-capturing-integration.js +8 -9
- package/integrations/tests/doubles/dummy-integration-class.js +8 -81
- package/integrations/tests/doubles/test-integration-repository.js +11 -51
- package/integrations/use-cases/create-integration.js +32 -36
- package/integrations/use-cases/create-process.js +9 -20
- package/integrations/use-cases/delete-integration-for-user.js +4 -5
- package/integrations/use-cases/get-integration-for-user.js +10 -25
- package/integrations/use-cases/get-integration-instance-by-definition.js +7 -13
- package/integrations/use-cases/get-integrations-for-user.js +1 -4
- package/integrations/use-cases/get-possible-integrations.js +1 -1
- package/integrations/use-cases/get-process.js +6 -5
- package/integrations/use-cases/index.js +1 -3
- package/integrations/use-cases/load-integration-context.js +5 -1
- package/integrations/use-cases/update-process-state.js +8 -10
- package/integrations/utils/map-integration-dto.js +3 -9
- package/jest-setup.js +1 -1
- package/jest-teardown.js +1 -1
- package/lambda/TimeoutCatcher.js +30 -32
- package/lambda/index.js +1 -1
- package/logs/index.js +3 -3
- package/modules/module.js +1 -3
- package/modules/repositories/module-repository-documentdb.js +48 -114
- package/modules/repositories/module-repository-interface.js +0 -13
- package/modules/repositories/module-repository-mongo.js +6 -46
- package/modules/repositories/module-repository-postgres.js +6 -48
- package/modules/repositories/module-repository.js +1 -34
- package/modules/requester/api-key.js +2 -0
- package/modules/requester/basic.js +1 -0
- package/modules/requester/oauth-2.js +2 -3
- package/modules/test/mock-api/definition.js +10 -15
- package/modules/test/mock-api/mocks/hubspot.js +36 -36
- package/modules/tests/doubles/test-module-factory.js +4 -10
- package/modules/tests/doubles/test-module-repository.js +1 -1
- package/modules/use-cases/get-entities-for-user.js +1 -1
- package/modules/use-cases/get-entity-options-by-id.js +6 -8
- package/modules/use-cases/get-module.js +9 -12
- package/modules/use-cases/process-authorization-callback.js +6 -12
- package/modules/use-cases/refresh-entity-options.js +6 -8
- package/modules/use-cases/test-module-auth.js +6 -8
- package/modules/utils/map-module-dto.js +2 -2
- package/package.json +5 -7
- package/prisma-mongodb/schema.prisma +33 -75
- package/prisma-postgresql/schema.prisma +33 -73
- package/queues/queuer-util.js +1 -5
- package/syncs/model.js +51 -51
- package/syncs/repositories/sync-repository-documentdb.js +19 -39
- package/syncs/repositories/sync-repository-interface.js +2 -6
- package/syncs/repositories/sync-repository-postgres.js +13 -19
- package/syncs/sync.js +100 -104
- package/token/repositories/token-repository-factory.js +3 -1
- package/types/assertions/index.d.ts +72 -72
- package/types/associations/index.d.ts +57 -57
- package/types/core/index.d.ts +53 -59
- package/types/database/index.d.ts +2 -2
- package/types/encrypt/index.d.ts +3 -3
- package/types/errors/index.d.ts +54 -61
- package/types/eslint-config/index.d.ts +40 -40
- package/types/integrations/index.d.ts +183 -185
- package/types/lambda/index.d.ts +26 -26
- package/types/logs/index.d.ts +4 -4
- package/types/module-plugin/index.d.ts +237 -239
- package/types/prettier-config/index.d.ts +5 -5
- package/types/syncs/index.d.ts +108 -102
- package/types/test-environment/index.d.ts +14 -14
- package/types/tsconfig.json +93 -95
- package/user/tests/doubles/test-user-repository.js +2 -5
- package/user/use-cases/authenticate-user.js +4 -2
- package/user/use-cases/authenticate-with-shared-secret.js +1 -1
- package/user/use-cases/create-individual-user.js +7 -8
- package/user/use-cases/create-organization-user.js +1 -1
- package/user/use-cases/create-token-for-user-id.js +1 -1
- package/user/use-cases/get-user-from-adopter-jwt.js +2 -0
- package/user/use-cases/get-user-from-bearer-token.js +3 -7
- package/user/use-cases/get-user-from-x-frigg-headers.js +11 -14
- package/user/use-cases/login-user.js +8 -8
- package/user/user.js +4 -18
- package/utils/backend-path.js +2 -2
- package/utils/index.js +1 -4
- package/websocket/repositories/websocket-connection-repository-documentdb.js +8 -21
- package/websocket/repositories/websocket-connection-repository-mongo.js +4 -8
- package/websocket/repositories/websocket-connection-repository-postgres.js +4 -8
- package/websocket/repositories/websocket-connection-repository.js +4 -8
- package/admin-scripts/repositories/admin-api-key-repository-interface.js +0 -121
- package/admin-scripts/repositories/admin-api-key-repository-mongo.js +0 -155
- package/admin-scripts/repositories/admin-api-key-repository-postgres.js +0 -189
- package/admin-scripts/repositories/script-execution-repository-documentdb.js +0 -21
- package/admin-scripts/repositories/script-execution-repository-factory.js +0 -55
- package/admin-scripts/repositories/script-execution-repository-interface.js +0 -193
- package/admin-scripts/repositories/script-execution-repository-mongo.js +0 -278
- package/admin-scripts/repositories/script-execution-repository-postgres.js +0 -320
- package/credential/credential-router.js +0 -262
- package/credential/use-cases/delete-credential-for-user.js +0 -50
- package/credential/use-cases/list-credentials-for-user.js +0 -31
- package/credential/use-cases/reauthorize-credential.js +0 -103
- package/handlers/routers/admin.js +0 -450
- package/handlers/routers/docs.js +0 -180
- package/handlers/routers/middleware/loadUser.js +0 -39
- package/handlers/routers/middleware/requireAdmin.js +0 -41
- package/handlers/routers/middleware/requireLoggedInUser.js +0 -19
- package/integrations/use-cases/execute-proxy-request.js +0 -564
- package/modules/domain/entities/AuthorizationSession.js +0 -131
- package/modules/domain/entities/index.js +0 -10
- package/modules/repositories/authorization-session-repository-factory.js +0 -55
- package/modules/repositories/authorization-session-repository-interface.js +0 -75
- package/modules/repositories/authorization-session-repository-mongo.js +0 -169
- package/modules/repositories/authorization-session-repository-postgres.js +0 -170
- package/modules/use-cases/delete-module-entity.js +0 -23
- package/modules/use-cases/get-authorization-requirements.js +0 -110
- package/modules/use-cases/get-module-entity-by-id.js +0 -16
- package/modules/use-cases/process-authorization-step.js +0 -160
- package/modules/use-cases/start-authorization-session.js +0 -86
- package/modules/use-cases/update-module-entity.js +0 -27
- package/openapi/openapi-spec-generator.js +0 -370
- package/openapi/openapi-v1.yaml +0 -1360
- package/openapi/openapi-v2.yaml +0 -1535
- package/user/use-cases/delete-user.js +0 -47
|
@@ -62,7 +62,7 @@ class TriggerDatabaseMigrationUseCase {
|
|
|
62
62
|
if (!queueUrl) {
|
|
63
63
|
throw new Error(
|
|
64
64
|
'DB_MIGRATION_QUEUE_URL environment variable is not set. ' +
|
|
65
|
-
|
|
65
|
+
'Cannot send migration to queue.'
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -77,9 +77,7 @@ class TriggerDatabaseMigrationUseCase {
|
|
|
77
77
|
queueUrl
|
|
78
78
|
);
|
|
79
79
|
|
|
80
|
-
console.log(
|
|
81
|
-
`Sent migration job to queue: ${migrationStatus.migrationId}`
|
|
82
|
-
);
|
|
80
|
+
console.log(`Sent migration job to queue: ${migrationStatus.migrationId}`);
|
|
83
81
|
} catch (error) {
|
|
84
82
|
console.error(`Failed to send migration to queue:`, error);
|
|
85
83
|
|
|
@@ -91,7 +89,9 @@ class TriggerDatabaseMigrationUseCase {
|
|
|
91
89
|
error: `Failed to queue migration: ${error.message}`,
|
|
92
90
|
});
|
|
93
91
|
|
|
94
|
-
throw new Error(
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Failed to queue migration: ${error.message}`
|
|
94
|
+
);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
// Return migration info immediately (don't wait for migration completion)
|
|
@@ -99,7 +99,7 @@ class TriggerDatabaseMigrationUseCase {
|
|
|
99
99
|
success: true,
|
|
100
100
|
migrationId: migrationStatus.migrationId,
|
|
101
101
|
state: migrationStatus.state,
|
|
102
|
-
statusUrl: `/db-migrate/${migrationStatus.migrationId}`,
|
|
102
|
+
statusUrl: `/admin/db-migrate/${migrationStatus.migrationId}`,
|
|
103
103
|
s3Key: `migrations/${migrationStatus.stage}/${migrationStatus.migrationId}.json`,
|
|
104
104
|
message: 'Database migration queued successfully',
|
|
105
105
|
};
|
|
@@ -126,9 +126,7 @@ class TriggerDatabaseMigrationUseCase {
|
|
|
126
126
|
const validDbTypes = ['postgresql', 'mongodb', 'documentdb'];
|
|
127
127
|
if (!validDbTypes.includes(dbType)) {
|
|
128
128
|
throw new ValidationError(
|
|
129
|
-
`Invalid dbType: "${dbType}". Must be one of: ${validDbTypes.join(
|
|
130
|
-
', '
|
|
131
|
-
)}`
|
|
129
|
+
`Invalid dbType: "${dbType}". Must be one of: ${validDbTypes.join(', ')}`
|
|
132
130
|
);
|
|
133
131
|
}
|
|
134
132
|
|
|
@@ -156,3 +154,4 @@ module.exports = {
|
|
|
156
154
|
TriggerDatabaseMigrationUseCase,
|
|
157
155
|
ValidationError,
|
|
158
156
|
};
|
|
157
|
+
|
|
@@ -46,10 +46,7 @@ async function ensureCollectionExists(collectionName) {
|
|
|
46
46
|
// This is expected in race conditions, silently continue
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
console.warn(
|
|
50
|
-
`Error ensuring collection ${collectionName} exists:`,
|
|
51
|
-
error.message
|
|
52
|
-
);
|
|
49
|
+
console.warn(`Error ensuring collection ${collectionName} exists:`, error.message);
|
|
53
50
|
}
|
|
54
51
|
}
|
|
55
52
|
|
|
@@ -65,9 +62,7 @@ async function ensureCollectionExists(collectionName) {
|
|
|
65
62
|
* ```
|
|
66
63
|
*/
|
|
67
64
|
async function ensureCollectionsExist(collectionNames) {
|
|
68
|
-
await Promise.all(
|
|
69
|
-
collectionNames.map((name) => ensureCollectionExists(name))
|
|
70
|
-
);
|
|
65
|
+
await Promise.all(collectionNames.map(name => ensureCollectionExists(name)));
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
/**
|
|
@@ -84,10 +79,7 @@ async function collectionExists(collectionName) {
|
|
|
84
79
|
|
|
85
80
|
return collections.length > 0;
|
|
86
81
|
} catch (error) {
|
|
87
|
-
console.error(
|
|
88
|
-
`Error checking if collection ${collectionName} exists:`,
|
|
89
|
-
error.message
|
|
90
|
-
);
|
|
82
|
+
console.error(`Error checking if collection ${collectionName} exists:`, error.message);
|
|
91
83
|
return false;
|
|
92
84
|
}
|
|
93
85
|
}
|
|
@@ -49,9 +49,7 @@ const config = require('../config');
|
|
|
49
49
|
async function initializeMongoDBSchema() {
|
|
50
50
|
// Only run for MongoDB-compatible databases
|
|
51
51
|
if (config.DB_TYPE !== 'mongodb' && config.DB_TYPE !== 'documentdb') {
|
|
52
|
-
console.log(
|
|
53
|
-
'Schema initialization skipped - not using MongoDB-compatible database'
|
|
54
|
-
);
|
|
52
|
+
console.log('Schema initialization skipped - not using MongoDB-compatible database');
|
|
55
53
|
return;
|
|
56
54
|
}
|
|
57
55
|
|
|
@@ -59,13 +57,11 @@ async function initializeMongoDBSchema() {
|
|
|
59
57
|
if (mongoose.connection.readyState !== 1) {
|
|
60
58
|
throw new Error(
|
|
61
59
|
'Cannot initialize MongoDB schema - database not connected. ' +
|
|
62
|
-
|
|
60
|
+
'Call connectPrisma() before initializeMongoDBSchema()'
|
|
63
61
|
);
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
console.log(
|
|
67
|
-
'Initializing MongoDB-compatible schema - ensuring all collections exist...'
|
|
68
|
-
);
|
|
64
|
+
console.log('Initializing MongoDB-compatible schema - ensuring all collections exist...');
|
|
69
65
|
const startTime = Date.now();
|
|
70
66
|
|
|
71
67
|
try {
|
|
@@ -73,9 +69,7 @@ async function initializeMongoDBSchema() {
|
|
|
73
69
|
const collections = getCollectionsFromSchemaSync();
|
|
74
70
|
|
|
75
71
|
if (collections.length === 0) {
|
|
76
|
-
console.warn(
|
|
77
|
-
'No collections found in Prisma schema - skipping initialization'
|
|
78
|
-
);
|
|
72
|
+
console.warn('No collections found in Prisma schema - skipping initialization');
|
|
79
73
|
return;
|
|
80
74
|
}
|
|
81
75
|
|
|
@@ -30,23 +30,8 @@ function getPrismaSchemaPath(dbType, projectRoot = process.cwd()) {
|
|
|
30
30
|
// Lambda layer path - this is where the schema actually exists in deployed Lambda
|
|
31
31
|
`/opt/nodejs/node_modules/generated/prisma-${normalizedType}/schema.prisma`,
|
|
32
32
|
// Check where Frigg is installed via npm (production scenario)
|
|
33
|
-
path.join(
|
|
34
|
-
|
|
35
|
-
'node_modules',
|
|
36
|
-
'@friggframework',
|
|
37
|
-
'core',
|
|
38
|
-
`prisma-${normalizedType}`,
|
|
39
|
-
'schema.prisma'
|
|
40
|
-
),
|
|
41
|
-
path.join(
|
|
42
|
-
projectRoot,
|
|
43
|
-
'..',
|
|
44
|
-
'node_modules',
|
|
45
|
-
'@friggframework',
|
|
46
|
-
'core',
|
|
47
|
-
`prisma-${normalizedType}`,
|
|
48
|
-
'schema.prisma'
|
|
49
|
-
),
|
|
33
|
+
path.join(projectRoot, 'node_modules', '@friggframework', 'core', `prisma-${normalizedType}`, 'schema.prisma'),
|
|
34
|
+
path.join(projectRoot, '..', 'node_modules', '@friggframework', 'core', `prisma-${normalizedType}`, 'schema.prisma')
|
|
50
35
|
];
|
|
51
36
|
|
|
52
37
|
for (const schemaPath of possiblePaths) {
|
|
@@ -58,7 +43,7 @@ function getPrismaSchemaPath(dbType, projectRoot = process.cwd()) {
|
|
|
58
43
|
// If not found in any location, throw error
|
|
59
44
|
throw new Error(
|
|
60
45
|
`Prisma schema not found at:\n${possiblePaths.join('\n')}\n\n` +
|
|
61
|
-
|
|
46
|
+
'Ensure @friggframework/core is installed.'
|
|
62
47
|
);
|
|
63
48
|
}
|
|
64
49
|
|
|
@@ -74,76 +59,57 @@ async function runPrismaGenerate(dbType, verbose = false) {
|
|
|
74
59
|
|
|
75
60
|
// Check if Prisma client already exists (e.g., in Lambda or pre-generated)
|
|
76
61
|
const normalizedType = normalizeMongoCompatible(dbType);
|
|
77
|
-
const generatedClientPath = path.join(
|
|
78
|
-
|
|
79
|
-
'generated',
|
|
80
|
-
`prisma-${normalizedType}`,
|
|
81
|
-
'client.js'
|
|
82
|
-
);
|
|
83
|
-
const isLambdaEnvironment =
|
|
84
|
-
!!process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
85
|
-
!!process.env.LAMBDA_TASK_ROOT;
|
|
62
|
+
const generatedClientPath = path.join(path.dirname(path.dirname(schemaPath)), 'generated', `prisma-${normalizedType}`, 'client.js');
|
|
63
|
+
const isLambdaEnvironment = !!process.env.AWS_LAMBDA_FUNCTION_NAME || !!process.env.LAMBDA_TASK_ROOT;
|
|
86
64
|
|
|
87
65
|
// In Lambda, also check the layer path (/opt/nodejs/node_modules)
|
|
88
66
|
const lambdaLayerClientPath = `/opt/nodejs/node_modules/generated/prisma-${normalizedType}/client.js`;
|
|
89
67
|
|
|
90
|
-
const clientExists =
|
|
91
|
-
fs.existsSync(generatedClientPath) ||
|
|
92
|
-
(isLambdaEnvironment && fs.existsSync(lambdaLayerClientPath));
|
|
68
|
+
const clientExists = fs.existsSync(generatedClientPath) || (isLambdaEnvironment && fs.existsSync(lambdaLayerClientPath));
|
|
93
69
|
|
|
94
70
|
if (clientExists) {
|
|
95
|
-
const foundPath = fs.existsSync(generatedClientPath)
|
|
96
|
-
? generatedClientPath
|
|
97
|
-
: lambdaLayerClientPath;
|
|
71
|
+
const foundPath = fs.existsSync(generatedClientPath) ? generatedClientPath : lambdaLayerClientPath;
|
|
98
72
|
if (verbose) {
|
|
99
|
-
|
|
100
|
-
chalk.gray(
|
|
101
|
-
`✓ Prisma client already generated at: ${foundPath}`
|
|
102
|
-
)
|
|
103
|
-
);
|
|
73
|
+
console.log(chalk.gray(`✓ Prisma client already generated at: ${foundPath}`));
|
|
104
74
|
}
|
|
105
75
|
if (isLambdaEnvironment) {
|
|
106
76
|
if (verbose) {
|
|
107
|
-
console.log(
|
|
108
|
-
chalk.gray(
|
|
109
|
-
'Skipping generation in Lambda environment (using pre-generated client)'
|
|
110
|
-
)
|
|
111
|
-
);
|
|
77
|
+
console.log(chalk.gray('Skipping generation in Lambda environment (using pre-generated client)'));
|
|
112
78
|
}
|
|
113
79
|
return {
|
|
114
80
|
success: true,
|
|
115
|
-
output: 'Using pre-generated Prisma client (Lambda environment)'
|
|
81
|
+
output: 'Using pre-generated Prisma client (Lambda environment)'
|
|
116
82
|
};
|
|
117
83
|
}
|
|
118
84
|
}
|
|
119
85
|
|
|
120
86
|
if (verbose) {
|
|
121
|
-
console.log(
|
|
122
|
-
chalk.gray(
|
|
123
|
-
`Running: npx prisma generate --schema=${schemaPath}`
|
|
124
|
-
)
|
|
125
|
-
);
|
|
87
|
+
console.log(chalk.gray(`Running: npx prisma generate --schema=${schemaPath}`));
|
|
126
88
|
}
|
|
127
89
|
|
|
128
|
-
const output = execSync(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
90
|
+
const output = execSync(
|
|
91
|
+
`npx prisma generate --schema=${schemaPath}`,
|
|
92
|
+
{
|
|
93
|
+
encoding: 'utf8',
|
|
94
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
95
|
+
env: {
|
|
96
|
+
...process.env,
|
|
97
|
+
// Suppress Prisma telemetry prompts
|
|
98
|
+
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
);
|
|
137
102
|
|
|
138
103
|
return {
|
|
139
104
|
success: true,
|
|
140
|
-
output: verbose ? 'Generated successfully' : output
|
|
105
|
+
output: verbose ? 'Generated successfully' : output
|
|
141
106
|
};
|
|
107
|
+
|
|
142
108
|
} catch (error) {
|
|
143
109
|
return {
|
|
144
110
|
success: false,
|
|
145
111
|
error: error.message,
|
|
146
|
-
output: error.stdout?.toString() || error.stderr?.toString()
|
|
112
|
+
output: error.stdout?.toString() || error.stderr?.toString()
|
|
147
113
|
};
|
|
148
114
|
}
|
|
149
115
|
}
|
|
@@ -169,14 +135,17 @@ async function checkDatabaseState(dbType) {
|
|
|
169
135
|
? `${prismaBin} migrate status --schema=${schemaPath}`
|
|
170
136
|
: `npx prisma migrate status --schema=${schemaPath}`;
|
|
171
137
|
|
|
172
|
-
const output = execSync(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
138
|
+
const output = execSync(
|
|
139
|
+
command,
|
|
140
|
+
{
|
|
141
|
+
encoding: 'utf8',
|
|
142
|
+
stdio: 'pipe',
|
|
143
|
+
env: {
|
|
144
|
+
...process.env,
|
|
145
|
+
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
);
|
|
180
149
|
|
|
181
150
|
if (output.includes('Database schema is up to date')) {
|
|
182
151
|
return { upToDate: true };
|
|
@@ -188,25 +157,26 @@ async function checkDatabaseState(dbType) {
|
|
|
188
157
|
|
|
189
158
|
return {
|
|
190
159
|
upToDate: false,
|
|
191
|
-
pendingMigrations
|
|
160
|
+
pendingMigrations
|
|
192
161
|
};
|
|
162
|
+
|
|
193
163
|
} catch (error) {
|
|
194
164
|
// If migrate status fails, database might not be initialized
|
|
195
165
|
return {
|
|
196
166
|
upToDate: false,
|
|
197
|
-
error: error.message
|
|
167
|
+
error: error.message
|
|
198
168
|
};
|
|
199
169
|
}
|
|
200
170
|
}
|
|
201
171
|
|
|
202
172
|
/**
|
|
203
173
|
* Gets the path to the Prisma CLI entry point
|
|
204
|
-
*
|
|
174
|
+
*
|
|
205
175
|
* IMPORTANT: We invoke prisma/build/index.js directly instead of .bin/prisma
|
|
206
176
|
* because .bin/prisma uses __dirname to find WASM files, and when the symlink
|
|
207
177
|
* is resolved during Lambda packaging, __dirname points to .bin/ instead of
|
|
208
178
|
* prisma/build/, causing WASM files to not be found.
|
|
209
|
-
*
|
|
179
|
+
*
|
|
210
180
|
* @returns {string} Command to run Prisma CLI (e.g., 'node /path/to/index.js' or 'npx prisma')
|
|
211
181
|
*/
|
|
212
182
|
function getPrismaBinaryPath() {
|
|
@@ -225,13 +195,7 @@ function getPrismaBinaryPath() {
|
|
|
225
195
|
}
|
|
226
196
|
|
|
227
197
|
// Check local node_modules - use actual CLI location
|
|
228
|
-
const localPrisma = path.join(
|
|
229
|
-
process.cwd(),
|
|
230
|
-
'node_modules',
|
|
231
|
-
'prisma',
|
|
232
|
-
'build',
|
|
233
|
-
'index.js'
|
|
234
|
-
);
|
|
198
|
+
const localPrisma = path.join(process.cwd(), 'node_modules', 'prisma', 'build', 'index.js');
|
|
235
199
|
if (fs.existsSync(localPrisma)) {
|
|
236
200
|
return `node ${localPrisma}`;
|
|
237
201
|
}
|
|
@@ -252,9 +216,7 @@ async function runPrismaMigrate(command = 'dev', verbose = false) {
|
|
|
252
216
|
const schemaPath = getPrismaSchemaPath('postgresql');
|
|
253
217
|
|
|
254
218
|
// Get Prisma binary path (checks multiple locations)
|
|
255
|
-
const isLambdaEnvironment =
|
|
256
|
-
!!process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
257
|
-
!!process.env.LAMBDA_TASK_ROOT;
|
|
219
|
+
const isLambdaEnvironment = !!process.env.AWS_LAMBDA_FUNCTION_NAME || !!process.env.LAMBDA_TASK_ROOT;
|
|
258
220
|
const prismaBin = getPrismaBinaryPath();
|
|
259
221
|
|
|
260
222
|
// Determine args based on whether we're using direct binary or npx
|
|
@@ -280,14 +242,14 @@ async function runPrismaMigrate(command = 'dev', verbose = false) {
|
|
|
280
242
|
stdio: 'inherit',
|
|
281
243
|
env: {
|
|
282
244
|
...process.env,
|
|
283
|
-
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
284
|
-
}
|
|
245
|
+
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
246
|
+
}
|
|
285
247
|
});
|
|
286
248
|
|
|
287
249
|
proc.on('error', (error) => {
|
|
288
250
|
resolve({
|
|
289
251
|
success: false,
|
|
290
|
-
error: error.message
|
|
252
|
+
error: error.message
|
|
291
253
|
});
|
|
292
254
|
});
|
|
293
255
|
|
|
@@ -295,19 +257,20 @@ async function runPrismaMigrate(command = 'dev', verbose = false) {
|
|
|
295
257
|
if (code === 0) {
|
|
296
258
|
resolve({
|
|
297
259
|
success: true,
|
|
298
|
-
output: 'Migration completed successfully'
|
|
260
|
+
output: 'Migration completed successfully'
|
|
299
261
|
});
|
|
300
262
|
} else {
|
|
301
263
|
resolve({
|
|
302
264
|
success: false,
|
|
303
|
-
error: `Migration process exited with code ${code}
|
|
265
|
+
error: `Migration process exited with code ${code}`
|
|
304
266
|
});
|
|
305
267
|
}
|
|
306
268
|
});
|
|
269
|
+
|
|
307
270
|
} catch (error) {
|
|
308
271
|
resolve({
|
|
309
272
|
success: false,
|
|
310
|
-
error: error.message
|
|
273
|
+
error: error.message
|
|
311
274
|
});
|
|
312
275
|
}
|
|
313
276
|
});
|
|
@@ -330,7 +293,7 @@ async function runPrismaDbPush(verbose = false, nonInteractive = false) {
|
|
|
330
293
|
'push',
|
|
331
294
|
'--schema',
|
|
332
295
|
schemaPath,
|
|
333
|
-
'--skip-generate'
|
|
296
|
+
'--skip-generate' // We generate separately
|
|
334
297
|
];
|
|
335
298
|
|
|
336
299
|
// Add non-interactive flag for Lambda/CI environments
|
|
@@ -343,25 +306,17 @@ async function runPrismaDbPush(verbose = false, nonInteractive = false) {
|
|
|
343
306
|
}
|
|
344
307
|
|
|
345
308
|
if (nonInteractive) {
|
|
346
|
-
console.log(
|
|
347
|
-
chalk.yellow(
|
|
348
|
-
'⚠️ Non-interactive mode: Data loss will be automatically accepted'
|
|
349
|
-
)
|
|
350
|
-
);
|
|
309
|
+
console.log(chalk.yellow('⚠️ Non-interactive mode: Data loss will be automatically accepted'));
|
|
351
310
|
} else {
|
|
352
|
-
console.log(
|
|
353
|
-
chalk.yellow(
|
|
354
|
-
'⚠️ Interactive mode: You may be prompted if schema changes cause data loss'
|
|
355
|
-
)
|
|
356
|
-
);
|
|
311
|
+
console.log(chalk.yellow('⚠️ Interactive mode: You may be prompted if schema changes cause data loss'));
|
|
357
312
|
}
|
|
358
313
|
|
|
359
314
|
const proc = spawn('npx', args, {
|
|
360
315
|
stdio: nonInteractive ? 'pipe' : 'inherit', // Use pipe for non-interactive to capture output
|
|
361
316
|
env: {
|
|
362
317
|
...process.env,
|
|
363
|
-
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
364
|
-
}
|
|
318
|
+
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
319
|
+
}
|
|
365
320
|
});
|
|
366
321
|
|
|
367
322
|
let stdout = '';
|
|
@@ -390,7 +345,7 @@ async function runPrismaDbPush(verbose = false, nonInteractive = false) {
|
|
|
390
345
|
proc.on('error', (error) => {
|
|
391
346
|
resolve({
|
|
392
347
|
success: false,
|
|
393
|
-
error: error.message
|
|
348
|
+
error: error.message
|
|
394
349
|
});
|
|
395
350
|
});
|
|
396
351
|
|
|
@@ -398,22 +353,21 @@ async function runPrismaDbPush(verbose = false, nonInteractive = false) {
|
|
|
398
353
|
if (code === 0) {
|
|
399
354
|
resolve({
|
|
400
355
|
success: true,
|
|
401
|
-
output: nonInteractive
|
|
402
|
-
? stdout || 'Database push completed successfully'
|
|
403
|
-
: 'Database push completed successfully',
|
|
356
|
+
output: nonInteractive ? stdout || 'Database push completed successfully' : 'Database push completed successfully'
|
|
404
357
|
});
|
|
405
358
|
} else {
|
|
406
359
|
resolve({
|
|
407
360
|
success: false,
|
|
408
361
|
error: `Database push process exited with code ${code}`,
|
|
409
|
-
output: stderr || stdout
|
|
362
|
+
output: stderr || stdout
|
|
410
363
|
});
|
|
411
364
|
}
|
|
412
365
|
});
|
|
366
|
+
|
|
413
367
|
} catch (error) {
|
|
414
368
|
resolve({
|
|
415
369
|
success: false,
|
|
416
|
-
error: error.message
|
|
370
|
+
error: error.message
|
|
417
371
|
});
|
|
418
372
|
}
|
|
419
373
|
});
|
|
@@ -426,11 +380,7 @@ async function runPrismaDbPush(verbose = false, nonInteractive = false) {
|
|
|
426
380
|
* @param {boolean} verbose - Enable verbose output
|
|
427
381
|
* @returns {Promise<Object>} { success: boolean, output?: string, error?: string }
|
|
428
382
|
*/
|
|
429
|
-
async function runPrismaMigrateResolve(
|
|
430
|
-
migrationName,
|
|
431
|
-
action = 'applied',
|
|
432
|
-
verbose = false
|
|
433
|
-
) {
|
|
383
|
+
async function runPrismaMigrateResolve(migrationName, action = 'applied', verbose = false) {
|
|
434
384
|
return new Promise((resolve) => {
|
|
435
385
|
try {
|
|
436
386
|
const schemaPath = getPrismaSchemaPath('postgresql');
|
|
@@ -441,23 +391,8 @@ async function runPrismaMigrateResolve(
|
|
|
441
391
|
// Determine args based on whether we're using direct binary or npx
|
|
442
392
|
const isDirectBinary = prismaBin !== 'npx prisma';
|
|
443
393
|
const args = isDirectBinary
|
|
444
|
-
? [
|
|
445
|
-
|
|
446
|
-
'resolve',
|
|
447
|
-
`--${action}`,
|
|
448
|
-
migrationName,
|
|
449
|
-
'--schema',
|
|
450
|
-
schemaPath,
|
|
451
|
-
]
|
|
452
|
-
: [
|
|
453
|
-
'prisma',
|
|
454
|
-
'migrate',
|
|
455
|
-
'resolve',
|
|
456
|
-
`--${action}`,
|
|
457
|
-
migrationName,
|
|
458
|
-
'--schema',
|
|
459
|
-
schemaPath,
|
|
460
|
-
];
|
|
394
|
+
? ['migrate', 'resolve', `--${action}`, migrationName, '--schema', schemaPath]
|
|
395
|
+
: ['prisma', 'migrate', 'resolve', `--${action}`, migrationName, '--schema', schemaPath];
|
|
461
396
|
|
|
462
397
|
if (verbose) {
|
|
463
398
|
const displayCmd = isDirectBinary
|
|
@@ -474,14 +409,14 @@ async function runPrismaMigrateResolve(
|
|
|
474
409
|
stdio: 'inherit',
|
|
475
410
|
env: {
|
|
476
411
|
...process.env,
|
|
477
|
-
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
478
|
-
}
|
|
412
|
+
PRISMA_HIDE_UPDATE_MESSAGE: '1'
|
|
413
|
+
}
|
|
479
414
|
});
|
|
480
415
|
|
|
481
416
|
proc.on('error', (error) => {
|
|
482
417
|
resolve({
|
|
483
418
|
success: false,
|
|
484
|
-
error: error.message
|
|
419
|
+
error: error.message
|
|
485
420
|
});
|
|
486
421
|
});
|
|
487
422
|
|
|
@@ -489,19 +424,20 @@ async function runPrismaMigrateResolve(
|
|
|
489
424
|
if (code === 0) {
|
|
490
425
|
resolve({
|
|
491
426
|
success: true,
|
|
492
|
-
output: `Migration ${migrationName} marked as ${action}
|
|
427
|
+
output: `Migration ${migrationName} marked as ${action}`
|
|
493
428
|
});
|
|
494
429
|
} else {
|
|
495
430
|
resolve({
|
|
496
431
|
success: false,
|
|
497
|
-
error: `Resolve process exited with code ${code}
|
|
432
|
+
error: `Resolve process exited with code ${code}`
|
|
498
433
|
});
|
|
499
434
|
}
|
|
500
435
|
});
|
|
436
|
+
|
|
501
437
|
} catch (error) {
|
|
502
438
|
resolve({
|
|
503
439
|
success: false,
|
|
504
|
-
error: error.message
|
|
440
|
+
error: error.message
|
|
505
441
|
});
|
|
506
442
|
}
|
|
507
443
|
});
|
|
@@ -514,18 +450,12 @@ async function runPrismaMigrateResolve(
|
|
|
514
450
|
*/
|
|
515
451
|
function getMigrationCommand(stage) {
|
|
516
452
|
// Always use 'deploy' in Lambda environment (it's non-interactive and doesn't create migrations)
|
|
517
|
-
const isLambdaEnvironment =
|
|
518
|
-
!!process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
519
|
-
!!process.env.LAMBDA_TASK_ROOT;
|
|
453
|
+
const isLambdaEnvironment = !!process.env.AWS_LAMBDA_FUNCTION_NAME || !!process.env.LAMBDA_TASK_ROOT;
|
|
520
454
|
if (isLambdaEnvironment) {
|
|
521
455
|
return 'deploy';
|
|
522
456
|
}
|
|
523
457
|
|
|
524
|
-
const normalizedStage = (
|
|
525
|
-
stage ||
|
|
526
|
-
process.env.STAGE ||
|
|
527
|
-
'development'
|
|
528
|
-
).toLowerCase();
|
|
458
|
+
const normalizedStage = (stage || process.env.STAGE || 'development').toLowerCase();
|
|
529
459
|
|
|
530
460
|
const developmentStages = ['dev', 'local', 'test', 'development'];
|
|
531
461
|
|
|
@@ -543,5 +473,5 @@ module.exports = {
|
|
|
543
473
|
runPrismaMigrate,
|
|
544
474
|
runPrismaMigrateResolve,
|
|
545
475
|
runPrismaDbPush,
|
|
546
|
-
getMigrationCommand
|
|
476
|
+
getMigrationCommand
|
|
547
477
|
};
|
|
@@ -146,7 +146,7 @@ async function getCollectionsFromSchema() {
|
|
|
146
146
|
if (!schemaPath) {
|
|
147
147
|
throw new Error(
|
|
148
148
|
'Could not find Prisma MongoDB schema file. ' +
|
|
149
|
-
|
|
149
|
+
'Searched: prisma-mongodb/schema.prisma, prisma/schema.prisma, schema.prisma'
|
|
150
150
|
);
|
|
151
151
|
}
|
|
152
152
|
|
|
@@ -165,7 +165,7 @@ function getCollectionsFromSchemaSync() {
|
|
|
165
165
|
if (!schemaPath) {
|
|
166
166
|
throw new Error(
|
|
167
167
|
'Could not find Prisma MongoDB schema file. ' +
|
|
168
|
-
|
|
168
|
+
'Searched: prisma-mongodb/schema.prisma, prisma/schema.prisma, schema.prisma'
|
|
169
169
|
);
|
|
170
170
|
}
|
|
171
171
|
|