diff --git a/.eslintrc.js b/.eslintrc.js index 6cfab43..6c95b94 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,7 +1,7 @@ module.exports = { - extends: ["plugin:prettier/recommended"], - parserOptions: { - ecmaVersion: "latest", - sourceType: "module" - } + extends: ['plugin:prettier/recommended'], + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module' + } }; diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4892485..924c49f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,53 +1,54 @@ name: Release on: - workflow_dispatch: + workflow_dispatch: jobs: - release: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [macos-latest, ubuntu-latest, windows-latest] - - steps: - - name: Check out Git repository - uses: actions/checkout@v4 - - - name: Install Node.js and npm - uses: actions/setup-node@v4 - with: - node-version: "22.x" - - - name: Install dependencies - run: npm install --force - - - name: Updater - run: git update-index --chmod=+x ./gen-update-xml.sh && sh ./gen-update-xml.sh - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - - - name: Install Snapcraft - if: matrix.os == 'ubuntu-latest' - run: | - sudo snap install snapcraft --classic - - - name: 🐧 Release Linux - if: matrix.os == 'ubuntu-latest' - run: npm run publish:linux - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} - - - name: 💻 Release Windows - if: matrix.os == 'windows-latest' - run: npm run publish:win - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - - - name: Release Mac - if: matrix.os == 'macos-latest' - run: npm run publish:mac - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} + release: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + + steps: + - name: Check out Git repository + uses: actions/checkout@v4 + + - name: Install Node.js and npm + uses: actions/setup-node@v4 + with: + node-version: '22.x' + + - name: Install dependencies + run: npm install --force + + - name: Updater + run: git update-index --chmod=+x ./gen-update-xml.sh && sh ./gen-update-xml.sh + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + + - name: 🐧 Release Linux + if: matrix.os == 'ubuntu-latest' + run: npm run publish:linux + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} + + - name: 💻 Release Windows + if: matrix.os == 'windows-latest' + run: npm run publish:win + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + + - name: 🍎 Release Mac Intel + if: matrix.os == 'macos-latest' + run: npm run publish:mac-intel + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + + - name: 🍎 Release Mac Apple Silicon + if: matrix.os == 'macos-latest' + run: npm run publish:mac-apple + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} diff --git a/.gitignore b/.gitignore index c2ad2bf..34313c0 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,6 @@ Thumbs.db *.zip *.tar.gz -7za \ No newline at end of file +7za + +/dist-electron/ \ No newline at end of file diff --git a/LICENSE b/LICENSE index bad8039..4d0d8ed 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 LaraBase +Copyright (c) 2025 Larabase Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index c8f3706..e69de29 100644 --- a/README.md +++ b/README.md @@ -1,146 +0,0 @@ -# Larabase - -
+ The database connection is not available or has + failed. +
+| + + | + +
+
+ {{
+ column.field
+ }}
+
+
+
+
+
+ |
+
|---|---|
| + + | + +
+
+ {{
+ formatCellValue(
+ column.field,
+ row[column.field]
+ )
+ }}
+
+
+
+ |
+
+ Loading database schema... +
++ Building entity-relationship diagram... +
+No Laravel project path selected
+Could not load .env file
+ ++ Custom Laravel commands should be in + app/Console/Commands directory +
+| # | +Class | +Command Signature | +Actions | +
|---|---|---|---|
| + {{ index + 1 }} + | ++ {{ command.name }} + | ++ {{ command.signature || '-' }} + | +
+
+
+
+
+ |
+
Command:
++ This command will be executed within your Laravel project + directory. +
+ +Command Information:
++ Required parameters: + {{ + getParameterList( + selectedCommand.signature, + '{', + '}' + ) + }} +
++ Optional parameters: + {{ + getParameterList( + selectedCommand.signature, + '[', + ']' + ) + }} +
+Perform database operations to see them appear here
+| Action | +Table | +Record ID | +Time | +View | ++ |
|---|---|---|---|---|---|
|
+
+ {{ log.action_type }}
+
+ |
+
+
+ {{ log.table_name }}
+
+ |
+
+
+
+ {{ log.record_id }}
+
+ {{ log.record_id }}
+
+ |
+ + {{ + formatTimestamp(log.created_at) + }} + | ++ + | ++ + | +
+ Table: + {{ selectedLog.table_name }} +
++ Record ID: + {{ selectedLog.record_id }} +
++ Time: + {{ formatFullDate(selectedLog.created_at) }} +
+{{
+ formatDetails(selectedLog.details)
+ }}
+ + No pending migrations found. +
+| # | +Migration Name | +Actions | +
|---|---|---|
| {{ index + 1 }} | ++ {{ migration }} + | +
+
+
+
+
+ |
+
+ No applied migrations found. +
+| # | +Migration Name | +
|---|---|
| + {{ index + 1 }} + | ++ {{ migration }} + | +
+ {{ selectedProject?.usingSail ? 'sail' : 'php' }}
+ artisan migrate:rollback --step={{ rollbackStep }}
+
+
+ | # | +Migration Name | +
|---|---|
| {{ index + 1 }} | ++ {{ migration }} + | +
+ Move the slider to select migrations to roll back +
++ Select at least one migration to enable rollback +
+
+ + Try changing your search criteria +
+| # | +Level | +Message | +Actions | +
|---|---|---|---|
| + {{ + (logsStore.currentPage - 1) * + logsStore.itemsPerPage + + index + + 1 + }} + | ++ + {{ entry.level }} + + | ++ {{ entry.message }} + | +
+
+
+
+
+ |
+
{{
+ selectedLogEntry.content.join('\n')
+ }}
+ Are you sure you want to delete this specific log entry?
++ {{ logToDelete?.message }} +
+Are you sure you want to clear the content of all logs?
+Are you sure you want to delete the entire log file?
++ {{ logsStore.selectedLogFile.name }} +
++ Select a database to view keys +
+Redis is not available for this connection.
++ Check your Redis configuration in the project settings. +
+{{ response }}
+ {{ queryPreview }}
+ + Analyzing query execution plan... +
+| + {{ key }} + | +
|---|
| + {{ value !== null ? value : 'NULL' }} + | +
Generating AI analysis...
++ Configure an AI provider in settings to get intelligent + optimization suggestions for your query. +
++ Click "Request AI Analysis" to get optimization + suggestions for your query. +
+No scratches found
++ Name: {{ projectStore.selectedProject?.name }} +
++ Project Path: + {{ projectStore.selectedProject?.projectPath }} +
+Database: {{ projectStore.targetDatabase }}
++ Project Database: + {{ projectStore.state.projectDatabase || 'Not found' }} +
++ {{ + originalUpdateInfo.version || + updateInfo.version + }} +
++ {{ + formatDate( + originalUpdateInfo.releaseDate || + updateInfo.releaseDate + ) + }} +
++ Are you sure you want to delete database + {{ databaseToDelete }}? This action cannot be undone. +
++ Are you sure you want to truncate + {{ tabsStore.pinnedTables.length }} + + + table(s)? This will delete ALL records and cannot be undone. + +
+
+
+ Are you sure you want to delete
+ {{ selectedTables.length }} table(s)?
+
+
+ This action cannot be undone.
+
+ Are you sure you want to delete + {{ dataTableStore.selectedRows.length }} record(s)? This action + cannot be undone. +
+ + + +{{ updateError }}
+Exporting data...
++ Data to export: + {{ isFiltered ? 'Filtered data' : 'All data' }} + ({{ totalRecords }} records{{ + !exportAllRecords ? ' - current page only' : '' + }}) +
+{{ factoryStore.error }}
++ Factory files are typically located in + database/factories directory +
+ +| Attribute | +Value | +
|---|---|
| {{ attr.name }} | ++ {{ formatFactoryValue(attr.value) }} + | +
+ No factory attributes were detected for + {{ factoryStore.modelName }} +
++ The factory might be using a non-standard format +
++ No Laravel factory found for {{ props.tableName }} table +
++ Factory files are typically named ModelNameFactory.php +
+ +Available columns:
+Common operators:
++ This table has no foreign key relationships. +
+| Constraint Name | +Column | +Referenced Table | +Referenced Column | +On Update | +On Delete | +
|---|---|---|---|---|---|
| {{ fk.name }} | +{{ fk.column }} | +
+
+ {{ fk.referenced_table }}
+
+
+ |
+ {{ fk.referenced_column }} | ++ {{ + fk.on_update + }} + | ++ {{ + fk.on_delete + }} + | +
| Constraint Name | +Table | +Column | +Referenced Column | +On Update | +On Delete | +
|---|---|---|---|---|---|
| {{ fk.name }} | +
+
+ {{ fk.table }}
+
+
+ |
+ {{ fk.column }} | +{{ fk.referenced_column }} | ++ {{ + fk.on_update + }} + | ++ {{ + fk.on_delete + }} + | +
+ This table doesn't have any indexes +
+| # | +Index Name | +Type | +Columns | +Algorithm | +Cardinality | +Comment | +
|---|---|---|---|---|---|---|
| {{ i + 1 }} | +{{ index.name }} | ++ {{ index.type }} + | ++ {{ index.columns.join(', ') }} + | ++ {{ index.algorithm }} + | ++ {{ index.cardinality }} + | ++ {{ index.comment || '-' }} + | +
+ No migrations found for {{ props.tableName }} table +
+| + # + + ↓ + + | +Name | +Status | ++ Created At + + ↓ + + | +Actions | +Tools | +
|---|---|---|---|---|---|
| + {{ + migrationsStore.sortedMigrations.length - + index + }} + | ++ {{ + (migration as Migration).displayName || + (migration as Migration).name + }} + | ++ + {{ migration.status }} + + | ++ {{ + formatDate( + migration.created_at, + migration.name + ) + }} + | +
+
+
+ {{ action.type }}
+
+
+ No actions
+ |
+
+
+
+
+
+ |
+
+ No Laravel model found for {{ tableName }} table +
++ Models are typically named using singular form or with + different naming conventions +
+ +| Type | +Related Model | +Method | +Details | +
|---|---|---|---|
| + + {{ rel.type }} + + | +
+
+ {{ rel.relatedModel }}
+
+
+ |
+ {{ rel.methodName }} | +{{ rel.details }} | +
+ No relationships found in {{ model?.name }} +
+{{
+ expandedFields.has(column.name)
+ ? formatJson(props.record[column.name])
+ : getJsonPreview(
+ props.record[column.name]
+ )
+ }}
+
+
+ + {{ + expandedFields.has(column.name) + ? props.record[column.name] + : getLimitedText( + props.record[column.name] + ) + }} +
+ ++ Table structure information could not be loaded +
+| # | +column_name | +data_type | +is_nullable | +key | +default | +
|---|---|---|---|---|---|
| {{ index + 1 }} | +{{ column.name }} | +{{ column.type }} | ++ {{ column.nullable ? 'YES' : 'NO' }} + | ++ PK + FK + UNI + MUL + | ++ {{ column.default ?? 'NULL' }} + | +
+ Are you sure you want to truncate the + {{ props.tableName }} table? This will delete + ALL records and cannot be undone. +
++ User: + {{ + record + ? record.name || record.email || `ID: ${record.id}` + : '' + }} +
++ This will update the password for this user and hash it + using Laravel's bcrypt hashing. +
+{{ dockerInfo.message }}
++ Container: {{ dockerInfo.dockerContainerName }} +
++ + The system detected a MySQL Docker + container. Configuration has been + automatically adjusted. + + + Docker is available, but no MySQL container + was found running on port + {{ newConnection.db_config.port }}. A local + connection will be used. + + + Docker was not detected. A local connection + will be used. + +
++ {{ restoreStatus }} +
++ Please wait until the SQL file analysis is complete +
++ Please confirm to start the restoration process. +
++ {{ restoreStatus }} {{ Math.floor(restoreProgress) }}% +
+No databases found
+Select a key to view its value
+{{ formatValue(redisStore.keyValue) }}
+ {{ formatValue(item) }}
+ {{ formatValue(item) }}
+ {{ formatValue(item.value) }}
+ {{ formatValue(value) }}
+ No keys found
+| Column | +Type | +Nullable | +Default | +Extra | +
|---|---|---|---|---|
| + {{ column.name }} + PK + FK + | ++ {{ formatDataType(column.type) }} + | ++ {{ column.nullable ? 'Yes' : 'No' }} + | ++ {{ + column.default !== null + ? column.default + : '' + }} + | +{{ column.extra }} | +
{{
+ JSON.stringify(props.schemaData, null, 2)
+ }}
+ No pending migrations
-| Migration | -Action | -
|---|---|
| - {{ formatMigrationName(migration) }} - | -- - | -
No migrations to rollback
-{{ sanitizedOutput }}
- No command output
-No Laravel project path selected
- -Could not load .env file
- -No commands match your search: "{{ searchQuery }}"
-No Laravel commands found
- -| Timestamp | -Operation | -Table | -Record ID | -Details | -Actions | -
|---|---|---|---|---|---|
| - {{ formatTimestamp(update.timestamp) }} - | -- - {{ update.operation || update.type }} - - | -{{ update.table }} | -{{ update.recordId || "-" }} | -- {{ update.details || update.message || (update.sql ? "SQL Query" : "-") }} - | -- - - | -
- No Laravel Project Path Set
-To view logs, you need to set a Laravel project path for this connection.
- -No Logs Found
-The log file might exist, but no parsable logs were found.
-| Timestamp | -Type | -Message | -Actions | -
|---|---|---|---|
| - {{ formatTimestamp(log.timestamp) }} - | -- - {{ log.type }} - - | -- {{ log.message }} - | -- - | -
| - No logs found - | -|||
- Timestamp: - {{ formatTimestamp(selectedLog.timestamp, true) }} -
-- File: - {{ selectedLog.file }} -
-Stack Trace:
-Are you sure you want to delete all logs? This action cannot be undone.
-{{ confirmationMessage }}
-Loading Redis databases...
-Connection: {{ connectionInfo }}
-Running On: {{ redisRunningMode }}
-{{ sqlCode }}
- {{ eloquentCode }}
- {{ JSON.stringify(storageData, null, 2) }}
-
- Are you sure you want to delete {{ selectedTables.length }} table(s)?
-
- This action cannot be undone.
-
- Are you sure you want to delete database {{ databaseToDelete }}? This action cannot be undone. -
-- Are you sure you want to truncate {{ pinnedTabs.length }} - - table(s)? This will delete ALL records and cannot be undone. -
-- Name: - {{ connection.name }} -
-- Type: - {{ connection.type }} -
-- Host: - {{ connection.host }} -
-- Port: - {{ connection.port }} -
-- Database: - {{ connection.database }} -
-- Username: - {{ connection.username }} -
-- Path: - {{ connection.path }} -
-- Project Path: - {{ connection.projectPath }} -
-- Project Database: - - {{ projectDatabase }} - -
-{{ tip.description }}
- -{{ dockerInfo.message }}
-- Container: {{ dockerInfo.dockerContainerName }} -
-- The system detected a MySQL Docker container. Configuration has been automatically adjusted. - - Docker is available, but no MySQL container was found running on port - {{ newConnection?.value?.port }}. A local connection will be used. - - Docker was not detected. A local connection will be used. -
-- {{ restoreStatus }} -
-Please wait until the SQL file analysis is complete
-Please confirm to start the restoration process.
-{{ restoreStatus }} {{ Math.floor(restoreProgress) }}%
-| Database | -Keys | -Memory Used | -Actions | -
|---|---|---|---|
|
- {{ db.name }}
- {{ db.id }}
- |
- {{ db.keys }} | -{{ formatMemory(db.memory) }} | -
-
-
-
-
- |
-
No Redis Databases Found
-There are no Redis databases with keys available
- -No Laravel project path is associated with this connection
- -No Laravel factory found for {{ tableName }} table
-Factories are typically named using singular form and located in database/factories directory
- -Create test records for {{ tableName }}
- -Number of records:
-Assign to specific model:
-| ID | -Preview | -Action | -
|---|---|---|
| {{ record.id }} | -- {{ formatRecordPreview(record) }} - | -- - | -
Customize attributes:
-Command preview:
-{{ generateCommandPreview() }}
- {{ loadError }}
- -No foreign keys found in this table
- -| Name | -Local Column | -Referenced Table | -Referenced Column | -On Update | -On Delete | -
|---|---|---|---|---|---|
| - {{ fk.name }} - | -- {{ fk.column }} - | -- {{ fk.referenced_table }} - | -- {{ fk.referenced_column }} - | -- {{ fk.on_update }} - | -- {{ fk.on_delete }} - | -
| Name | -Table | -Column | -Referenced Column | -On Update | -On Delete | -
|---|---|---|---|---|---|
| - {{ fk.name }} - | -- {{ fk.table }} - | -- {{ fk.column }} - | -- {{ fk.referenced_column }} - | -- {{ fk.on_update }} - | -- {{ fk.on_delete }} - | -
{{ loadError }}
- -No indexes found in this table
- -| Name | -Type | -Columns | -Algorithm | -Cardinality | -Comment | -
|---|---|---|---|---|---|
| - {{ index.name }} - | -- {{ index.type }} - | -- {{ index.columns.join(", ") }} - | -- {{ index.algorithm }} - | -- {{ index.cardinality }} - | -- {{ index.comment }} - | -
{{ loadError }}
- -No Laravel project path is associated with this connection
- -No migrations found for {{ tableName }} table
- -No Laravel project path is associated with this connection
- -No Laravel model found for {{ tableName }} table
-Models are typically named using singular form or with different naming conventions
- -| Type | -Related Model | -Method | -Details | -
|---|---|---|---|
| - - {{ rel.type }} - - | -{{ rel.relatedModel }} | -{{ rel.methodName }} | -{{ rel.details }} | -
Code is hidden. Click Expand Code to view.
-{{ loadError }}
- -| Column Name | -Type | -Nullable | -Key | -Default | -Extra | -
|---|---|---|---|---|---|
|
-
-
-
-
- {{ column.name }}
-
- |
- - {{ column.type }} - | -- - - | -- PRI - FOR - UNI - | -- {{ column.default }} - NULL - | -- {{ column.extra }} - | -
No structure information available
- -{{ formatJson(record[column]) }}
- | - Preview - | -
-
- {{ column }}
-
-
-
-
-
-
-
-
-
-
-
-
- |
-
|---|---|
| - - | -
-
-
-
-
- {{ row[column] === null && tableDataStore.isForeignKeyColumn(column) ? "Not related" : Helpers.formatCellValue(column, row[column]) }}
-
-
-
-
-
-
-
-
- |
-
- Are you sure you want to delete - {{ tableDataStore.selectedRows.length }} record(s)? This action cannot be undone. -
- - - -No records match your filter
-{{ props.message }}
- -Exporting data...
-- Data to export: - {{ isFiltered ? "Filtered data" : "All data" }} - ({{ totalRecords }} records{{ !exportAllRecords ? " - current page only" : "" }}) -
-Available columns:
-Common operators:
-Records not found
- -- Are you sure you want to truncate the - {{ tableDataStore.tableName }} table? This will delete ALL records and cannot be undone. -
-User: {{ user ? user.name || user.email || `ID: ${user.id}` : "" }}
-This will update the password for this user and hash it using Laravel's bcrypt hashing.
-No tables open.
-- {{ connectionErrorMessage }} -
-{{ allTablesModelsJson }}
- Analyzing query performance...
-{{ errorMessage }}
- -
- | - {{ column }} - | -
|---|
| - {{ row[column] }} - | -
{{ insight.description }}
-Analyzing query execution plan with AI...
-Get advanced AI analysis of your query execution plan to identify optimization opportunities.
- -Enter a SQL query and click "Analyze Performance" to see the execution plan
-An opinionated database GUI for Laravel developers
-No connections found
-Create a new connection to get started
-- {{ connection.host || connection.path }} -
-- {{ connection.database }} -
-{{ errorMessage }}
- Run a query to see results
-| - {{ column }} - | -
|---|
| - - NULL - - - {{ JSON.stringify(row[column]) }} - - - {{ row[column] }} - - | -