Compare commits
9 Commits
@nhost/str
...
@nhost/das
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3601de3f85 | ||
|
|
ac9404610b | ||
|
|
63570db57c | ||
|
|
538ed78f5a | ||
|
|
b1a31ecb00 | ||
|
|
bac8ace434 | ||
|
|
2145243b19 | ||
|
|
a48dd5bf74 | ||
|
|
ef53df5cb3 |
13
README.md
13
README.md
@@ -495,6 +495,13 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Quentin Decré</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/elephant3">
|
||||
<img src="https://avatars.githubusercontent.com/u/48279149?v=4" width="100;" alt="elephant3"/>
|
||||
<br />
|
||||
<sub><b>Siarhei Lipchyk</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/altschuler">
|
||||
<img src="https://avatars.githubusercontent.com/u/956928?v=4" width="100;" alt="altschuler"/>
|
||||
@@ -522,15 +529,15 @@ Here are some ways of contributing to making Nhost better:
|
||||
<br />
|
||||
<sub><b>Vadim</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/TheRedLancer">
|
||||
<img src="https://avatars.githubusercontent.com/u/58493767?v=4" width="100;" alt="TheRedLancer"/>
|
||||
<br />
|
||||
<sub><b>Zach Burnaby</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/komninoschat">
|
||||
<img src="https://avatars.githubusercontent.com/u/29049104?v=4" width="100;" alt="komninoschat"/>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/dashboard
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- a48dd5bf: feat(dashboard): make backend port configurable
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
FROM node:16-alpine AS pruner
|
||||
RUN apk add --no-cache libc6-compat
|
||||
RUN apk update
|
||||
@@ -17,10 +16,13 @@ RUN apk update
|
||||
WORKDIR /app
|
||||
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV NEXT_PUBLIC_NHOST_PLATFORM false
|
||||
ENV NEXT_PUBLIC_NHOST_MIGRATIONS_URL http://localhost:9693
|
||||
ENV NEXT_PUBLIC_NHOST_HASURA_URL http://localhost:9695
|
||||
ENV NEXT_PUBLIC_ENV dev
|
||||
ENV NEXT_PUBLIC_NHOST_PLATFORM false
|
||||
|
||||
# placeholders for ports, will be replaced on runtime by entrypoint script
|
||||
ENV NEXT_PUBLIC_NHOST_MIGRATIONS_PORT __NEXT_PUBLIC_NHOST_MIGRATIONS_PORT__
|
||||
ENV NEXT_PUBLIC_NHOST_HASURA_PORT __NEXT_PUBLIC_NHOST_HASURA_PORT__
|
||||
ENV NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT __NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT__
|
||||
|
||||
RUN yarn global add pnpm@7.17.0
|
||||
COPY .gitignore .gitignore
|
||||
@@ -40,11 +42,14 @@ RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
USER nextjs
|
||||
|
||||
COPY --from=builder /app/dashboard/next.config.js .
|
||||
COPY --from=builder /app/dashboard/package.json .
|
||||
COPY --from=builder /app/dashboard/public ./dashboard/public
|
||||
COPY --chown=nextjs:nodejs dashboard/docker-entrypoint.sh .
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/dashboard/next.config.js .
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/dashboard/package.json .
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/dashboard/public ./dashboard/public
|
||||
|
||||
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/dashboard/.next/standalone/app ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/dashboard/.next/static ./dashboard/.next/static
|
||||
|
||||
CMD node dashboard/server.js
|
||||
ENTRYPOINT ["./docker-entrypoint.sh"]
|
||||
CMD ["node", "dashboard/server.js"]
|
||||
|
||||
@@ -30,31 +30,27 @@ First, you need to run the following command to start your backend locally:
|
||||
cd <your_nhost_project> && nhost dev
|
||||
```
|
||||
|
||||
Two environment variables are required to connect the Nhost Dashboard to your local backend:
|
||||
You can connect the Nhost Dashboard to your locally running backend by setting the following environment variables in `.env.development.local`:
|
||||
|
||||
- `NEXT_PUBLIC_NHOST_PLATFORM` should be set to `false`, because otherwise the Nhost Dashboard will try to connect to the Nhost platform.
|
||||
- `NEXT_PUBLIC_NHOST_MIGRATIONS_URL` should be set to `http://localhost:9693` unless Hasura is configured to run on a different port. This is the URL of Hasura's migrations endpoint.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
```bash
|
||||
NEXT_PUBLIC_ENV=dev
|
||||
NEXT_PUBLIC_NHOST_PLATFORM=false
|
||||
NEXT_PUBLIC_NHOST_MIGRATIONS_URL=http://localhost:9693
|
||||
```
|
||||
|
||||
### Full list of environment variables
|
||||
|
||||
| Name | Description |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------------ |
|
||||
| `NEXT_PUBLIC_NHOST_PLATFORM` | This should be set to `false` to connect the Nhost Dashboard to a locally running Nhost backend. |
|
||||
| `NEXT_PUBLIC_NHOST_MIGRATIONS_URL` | URL of Hasura's migrations endpoint. Used only if local development is enabled. |
|
||||
| `NEXT_PUBLIC_NHOST_HASURA_URL` | URL of the Hasura Console. Used only when `NEXT_PUBLIC_ENV` is `dev`. |
|
||||
| `NEXT_PUBLIC_ENV` | `dev`, `staging` or `prod`. Should be set to `dev` in most cases. |
|
||||
| `NEXT_PUBLIC_NHOST_BACKEND_URL` | Backend URL. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_STRIPE_PK` | Stripe public key. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_GITHUB_APP_INSTALL_URL` | URL of the GitHub application. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_ANALYTICS_WRITE_KEY` | Analytics key. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_NHOST_BRAGI_WEBSOCKET` | URL of the Bragi websocket. Not necessary for local development. |
|
||||
| Name | Description |
|
||||
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `NEXT_PUBLIC_ENV` | `dev`, `staging` or `prod`. Should be set to `dev` in most cases. |
|
||||
| `NEXT_PUBLIC_NHOST_PLATFORM` | This should be set to `false` to connect the Nhost Dashboard to a locally running Nhost backend. Setting this to `true` turns off local development. |
|
||||
| `NEXT_PUBLIC_NHOST_LOCAL_MIGRATIONS_PORT` | Custom port that was passed to the CLI. Used only if local development is enabled. Default: `9693` |
|
||||
| `NEXT_PUBLIC_NHOST_LOCAL_HASURA_PORT` | Custom port that was passed to the CLI. Used only if local development is enabled and `NEXT_PUBLIC_ENV` is `dev`. Default: `9695` |
|
||||
| `NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT` | Custom port that was passed to the CLI. Used only if local development is enabled. Default: `1337` |
|
||||
| `NEXT_PUBLIC_NHOST_BACKEND_URL` | Backend URL. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_STRIPE_PK` | Stripe public key. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_GITHUB_APP_INSTALL_URL` | URL of the GitHub application. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_ANALYTICS_WRITE_KEY` | Analytics key. Not necessary for local development. |
|
||||
| `NEXT_PUBLIC_NHOST_BRAGI_WEBSOCKET` | URL of the Bragi websocket. Not necessary for local development. |
|
||||
|
||||
## ESLint Rules
|
||||
|
||||
@@ -67,6 +63,7 @@ NEXT_PUBLIC_NHOST_MIGRATIONS_URL=http://localhost:9693
|
||||
| `import/extensions` | JS / TS files should be imported without file extensions. |
|
||||
| `react/jsx-filename-extension` | JSX should only appear in `.jsx` and `.tsx` files. |
|
||||
| `react/jsx-no-bind` | Further investigation must be made on the performance impact of functions directly passed as props to components. |
|
||||
| `import/order` | Until we have a better auto-formatter, we disable this rule. |
|
||||
| `import/no-extraneous-dependencies` | `devDependencies` should be excluded from the list of disallowed imports. |
|
||||
| `curly` | By default it only enforces curly braces for multi-line blocks, but it should be enforced for single-line blocks as well. |
|
||||
| `no-restricted-exports` | `export { default } from './module'` is used heavily in `@/ui/v2` which is a restricted export by default. |
|
||||
|
||||
15
dashboard/docker-entrypoint.sh
Executable file
15
dashboard/docker-entrypoint.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# read ports from env variables or use defaults
|
||||
NEXT_PUBLIC_NHOST_MIGRATIONS_PORT="${NEXT_PUBLIC_NHOST_MIGRATIONS_PORT:=9693}"
|
||||
NEXT_PUBLIC_NHOST_HASURA_PORT="${NEXT_PUBLIC_NHOST_HASURA_PORT:=9695}"
|
||||
NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT="${NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT:=1337}"
|
||||
|
||||
# replace placeholders
|
||||
find dashboard -type f -exec sed -i "s/__NEXT_PUBLIC_NHOST_MIGRATIONS_PORT__/${NEXT_PUBLIC_NHOST_MIGRATIONS_PORT}/g" {} +
|
||||
find dashboard -type f -exec sed -i "s/__NEXT_PUBLIC_NHOST_HASURA_PORT__/${NEXT_PUBLIC_NHOST_HASURA_PORT}/g" {} +
|
||||
find dashboard -type f -exec sed -i "s/__NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT__/${NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT}/g" {} +
|
||||
|
||||
exec "$@"
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/dashboard",
|
||||
"version": "0.4.3",
|
||||
"version": "0.5.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
|
||||
@@ -5,6 +5,7 @@ import Button from '@/ui/v2/Button';
|
||||
import ArrowSquareOutIcon from '@/ui/v2/icons/ArrowSquareOutIcon';
|
||||
import Link from '@/ui/v2/Link';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { LOCAL_HASURA_URL } from '@/utils/env';
|
||||
import { generateRemoteAppUrl } from '@/utils/helpers';
|
||||
import Image from 'next/image';
|
||||
|
||||
@@ -24,7 +25,7 @@ export function HasuraData({ close }: HasuraDataProps) {
|
||||
|
||||
const hasuraUrl =
|
||||
process.env.NEXT_PUBLIC_ENV === 'dev'
|
||||
? process.env.NEXT_PUBLIC_NHOST_HASURA_URL || 'http://localhost:9695'
|
||||
? LOCAL_HASURA_URL
|
||||
: generateRemoteAppUrl(currentApplication.subdomain);
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
} from '@/types/data-browser';
|
||||
import { getPreparedHasuraQuery } from '@/utils/dataBrowser/hasuraQueryHelpers';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
import prepareCreateColumnQuery from './prepareCreateColumnQuery';
|
||||
|
||||
export interface CreateColumnMigrationVariables {
|
||||
@@ -33,30 +34,27 @@ export default async function createColumnMigration({
|
||||
column,
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${table}_add_column_${column.name}`,
|
||||
down: [
|
||||
getPreparedHasuraQuery(
|
||||
dataSource,
|
||||
'ALTER TABLE %I.%I DROP COLUMN IF EXISTS %I',
|
||||
schema,
|
||||
table,
|
||||
column.name,
|
||||
),
|
||||
],
|
||||
up: args,
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${table}_add_column_${column.name}`,
|
||||
down: [
|
||||
getPreparedHasuraQuery(
|
||||
dataSource,
|
||||
'ALTER TABLE %I.%I DROP COLUMN IF EXISTS %I',
|
||||
schema,
|
||||
table,
|
||||
column.name,
|
||||
),
|
||||
],
|
||||
up: args,
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
} from '@/types/data-browser';
|
||||
import { getPreparedHasuraQuery } from '@/utils/dataBrowser/hasuraQueryHelpers';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
import prepareCreateTableQuery from './prepareCreateTableQuery';
|
||||
|
||||
export interface CreateTableMigrationVariables {
|
||||
@@ -27,29 +28,26 @@ export default async function createTableMigration({
|
||||
}: CreateTableMigrationOptions & CreateTableMigrationVariables) {
|
||||
const args = prepareCreateTableQuery({ dataSource, schema, table });
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `create_table_${schema}_${table.name}`,
|
||||
down: [
|
||||
getPreparedHasuraQuery(
|
||||
dataSource,
|
||||
'DROP TABLE IF EXISTS %I.%I',
|
||||
schema,
|
||||
table.name,
|
||||
),
|
||||
],
|
||||
up: args,
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `create_table_${schema}_${table.name}`,
|
||||
down: [
|
||||
getPreparedHasuraQuery(
|
||||
dataSource,
|
||||
'DROP TABLE IF EXISTS %I.%I',
|
||||
schema,
|
||||
table.name,
|
||||
),
|
||||
],
|
||||
up: args,
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
} from '@/types/data-browser';
|
||||
import { getPreparedHasuraQuery } from '@/utils/dataBrowser/hasuraQueryHelpers';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
|
||||
export interface DeleteColumnMigrationVariables {
|
||||
/**
|
||||
@@ -45,30 +46,27 @@ export default async function deleteColumnMigration({
|
||||
},
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${table}_drop_column_${column.id}`,
|
||||
down: recreateColumnArgs,
|
||||
up: [
|
||||
getPreparedHasuraQuery(
|
||||
dataSource,
|
||||
'ALTER TABLE %I.%I DROP COLUMN IF EXISTS %I CASCADE',
|
||||
schema,
|
||||
table,
|
||||
column.id,
|
||||
),
|
||||
],
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${table}_drop_column_${column.id}`,
|
||||
down: recreateColumnArgs,
|
||||
up: [
|
||||
getPreparedHasuraQuery(
|
||||
dataSource,
|
||||
'ALTER TABLE %I.%I DROP COLUMN IF EXISTS %I CASCADE',
|
||||
schema,
|
||||
table,
|
||||
column.id,
|
||||
),
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
getPreparedHasuraQuery,
|
||||
} from '@/utils/dataBrowser/hasuraQueryHelpers';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
|
||||
export interface DeleteTableMigrationVariables {
|
||||
/**
|
||||
@@ -39,32 +40,29 @@ export default async function deleteTable({
|
||||
),
|
||||
];
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `drop_table_${schema}_${table}`,
|
||||
down: [
|
||||
{
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
cascade: false,
|
||||
read_only: false,
|
||||
source: '',
|
||||
sql: getEmptyDownMigrationMessage(deleteTableArgs),
|
||||
},
|
||||
},
|
||||
],
|
||||
up: deleteTableArgs,
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `drop_table_${schema}_${table}`,
|
||||
down: [
|
||||
{
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
cascade: false,
|
||||
read_only: false,
|
||||
source: '',
|
||||
sql: getEmptyDownMigrationMessage(deleteTableArgs),
|
||||
},
|
||||
},
|
||||
],
|
||||
up: deleteTableArgs,
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
QueryResult,
|
||||
} from '@/types/data-browser';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
import prepareTrackForeignKeyRelationsMetadata from './prepareTrackForeignKeyRelationsMetadata';
|
||||
|
||||
export interface TrackForeignKeyRelationsMigrationVariables {
|
||||
@@ -45,23 +46,20 @@ export default async function trackForeignKeyRelationsMigration({
|
||||
foreignKeyRelations,
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `track_foreign_key_relations_${schema}_${table}`,
|
||||
down: [],
|
||||
up: creatableRelationships,
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `track_foreign_key_relations_${schema}_${table}`,
|
||||
down: [],
|
||||
up: creatableRelationships,
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
QueryResult,
|
||||
} from '@/types/data-browser';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
|
||||
export interface TrackTableMigrationVariables {
|
||||
/**
|
||||
@@ -23,32 +24,29 @@ export default async function trackTableMigration({
|
||||
adminSecret,
|
||||
table,
|
||||
}: TrackTableMigrationOptions & TrackTableMigrationVariables) {
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `add_existing_table_or_view_${schema}_${table.name}`,
|
||||
down: [
|
||||
{
|
||||
type: 'pg_untrack_table',
|
||||
args: { source: dataSource, table: { schema, name: table.name } },
|
||||
},
|
||||
],
|
||||
up: [
|
||||
{
|
||||
args: { source: dataSource, table: { schema, name: table.name } },
|
||||
type: 'pg_track_table',
|
||||
},
|
||||
],
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `add_existing_table_or_view_${schema}_${table.name}`,
|
||||
down: [
|
||||
{
|
||||
type: 'pg_untrack_table',
|
||||
args: { source: dataSource, table: { schema, name: table.name } },
|
||||
},
|
||||
],
|
||||
up: [
|
||||
{
|
||||
args: { source: dataSource, table: { schema, name: table.name } },
|
||||
type: 'pg_track_table',
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
} from '@/types/data-browser';
|
||||
import { getEmptyDownMigrationMessage } from '@/utils/dataBrowser/hasuraQueryHelpers';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
import prepareUpdateColumnQuery from './prepareUpdateColumnQuery';
|
||||
|
||||
export interface UpdateColumnMigrationVariables {
|
||||
@@ -65,22 +66,19 @@ export default async function updateColumnMigration({
|
||||
];
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${table}_alter_column_${originalColumn.name}`,
|
||||
down: columnUpdateDownMigration,
|
||||
up: columnUpdateUpMigration,
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${table}_alter_column_${originalColumn.name}`,
|
||||
down: columnUpdateDownMigration,
|
||||
up: columnUpdateUpMigration,
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
} from '@/types/data-browser';
|
||||
import { getEmptyDownMigrationMessage } from '@/utils/dataBrowser/hasuraQueryHelpers';
|
||||
import normalizeQueryError from '@/utils/dataBrowser/normalizeQueryError';
|
||||
import { LOCAL_MIGRATIONS_URL } from '@/utils/env';
|
||||
import prepareUpdateTableQuery from './prepareUpdateTableQuery';
|
||||
|
||||
export interface UpdateTableMigrationVariables {
|
||||
@@ -56,32 +57,29 @@ export default async function updateTableMigration({
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_NHOST_MIGRATIONS_URL}/apis/migrate`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${originalTable.table_name}`,
|
||||
down: [
|
||||
{
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
cascade: false,
|
||||
read_only: false,
|
||||
source: '',
|
||||
sql: getEmptyDownMigrationMessage(args),
|
||||
},
|
||||
},
|
||||
],
|
||||
up: args,
|
||||
}),
|
||||
const response = await fetch(`${LOCAL_MIGRATIONS_URL}/apis/migrate`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-hasura-admin-secret': adminSecret,
|
||||
},
|
||||
);
|
||||
body: JSON.stringify({
|
||||
dataSource,
|
||||
skip_execution: false,
|
||||
name: `alter_table_${schema}_${originalTable.table_name}`,
|
||||
down: [
|
||||
{
|
||||
type: 'run_sql',
|
||||
args: {
|
||||
cascade: false,
|
||||
read_only: false,
|
||||
source: '',
|
||||
sql: getEmptyDownMigrationMessage(args),
|
||||
},
|
||||
},
|
||||
],
|
||||
up: args,
|
||||
}),
|
||||
});
|
||||
|
||||
const responseData: [AffectedRowsResult, QueryResult<string[]>] | QueryError =
|
||||
await response.json();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { LOCAL_SUBDOMAIN } from '@/utils/env';
|
||||
import { isDevOrStaging } from '@/utils/helpers';
|
||||
import type { NhostClientConstructorParams } from '@nhost/nhost-js';
|
||||
import { NhostClient } from '@nhost/nhost-js';
|
||||
@@ -20,7 +21,7 @@ export function useAppClient(
|
||||
|
||||
if (process.env.NEXT_PUBLIC_ENV === 'dev') {
|
||||
return new NhostClient({
|
||||
subdomain: 'localhost:1337',
|
||||
subdomain: LOCAL_SUBDOMAIN,
|
||||
start: false,
|
||||
...options,
|
||||
});
|
||||
|
||||
36
dashboard/src/utils/env.ts
Normal file
36
dashboard/src/utils/env.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* URL of Hasura's Migration API. This is only used when local development is
|
||||
* enabled.
|
||||
*/
|
||||
export const LOCAL_MIGRATIONS_URL = `http://localhost:${
|
||||
process.env.NEXT_PUBLIC_NHOST_LOCAL_MIGRATIONS_PORT || 9693
|
||||
}`;
|
||||
|
||||
/**
|
||||
* Port of the locally running backend.s
|
||||
*/
|
||||
export const LOCAL_BACKEND_PORT =
|
||||
process.env.NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT;
|
||||
|
||||
/**
|
||||
* Local subdomain. This is only used when local development is enabled.
|
||||
*/
|
||||
export const LOCAL_SUBDOMAIN = LOCAL_BACKEND_PORT
|
||||
? `localhost:${LOCAL_BACKEND_PORT}`
|
||||
: 'localhost';
|
||||
|
||||
/**
|
||||
* URL of Hasura Console. This is only used when running the Nhost Dashboard
|
||||
* locally.
|
||||
*/
|
||||
export const LOCAL_HASURA_URL = `http://localhost:${
|
||||
process.env.NEXT_PUBLIC_NHOST_LOCAL_HASURA_PORT || 9695
|
||||
}`;
|
||||
|
||||
/**
|
||||
* Backend URL for the locally running instance. This is only used when running
|
||||
* the Nhost Dashboard locally.
|
||||
*/
|
||||
export const LOCAL_BACKEND_URL = `http://localhost:${
|
||||
process.env.NEXT_PUBLIC_NHOST_LOCAL_BACKEND_PORT || 1337
|
||||
}`;
|
||||
@@ -6,6 +6,7 @@ import features from '@/data/features.json';
|
||||
import { ApplicationStatus } from '@/types/application';
|
||||
import type { NextRouter } from 'next/router';
|
||||
import slugify from 'slugify';
|
||||
import { LOCAL_BACKEND_URL } from './env';
|
||||
import type { DeploymentRowFragment } from './__generated__/graphql';
|
||||
|
||||
export function getLastLiveDeployment(deployments: DeploymentRowFragment[]) {
|
||||
@@ -57,11 +58,11 @@ export function getCurrentEnvironment(): Environment {
|
||||
|
||||
export function generateRemoteAppUrl(subdomain: string): string {
|
||||
if (process.env.NEXT_PUBLIC_NHOST_PLATFORM !== 'true') {
|
||||
return 'http://localhost:1337';
|
||||
return LOCAL_BACKEND_URL;
|
||||
}
|
||||
|
||||
if (process.env.NEXT_PUBLIC_ENV === 'dev') {
|
||||
return process.env.NEXT_PUBLIC_NHOST_BACKEND_URL || 'http://localhost:1337';
|
||||
return process.env.NEXT_PUBLIC_NHOST_BACKEND_URL || LOCAL_BACKEND_URL;
|
||||
}
|
||||
|
||||
if (process.env.NEXT_PUBLIC_ENV === 'staging') {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { NhostClient } from '@nhost/nextjs';
|
||||
import { LOCAL_SUBDOMAIN } from './env';
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: process.env.NEXT_PUBLIC_NHOST_BACKEND_URL as string,
|
||||
});
|
||||
export const nhost =
|
||||
process.env.NEXT_PUBLIC_NHOST_PLATFORM === 'true'
|
||||
? new NhostClient({ backendUrl: process.env.NEXT_PUBLIC_NHOST_BACKEND_URL })
|
||||
: new NhostClient({ subdomain: LOCAL_SUBDOMAIN });
|
||||
|
||||
export { nhost };
|
||||
export default nhost;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NhostClientConstructorParams } from './types'
|
||||
|
||||
const LOCALHOST_REGEX = /^((?<protocol>http[s]?):\/\/)?(?<host>localhost)(:(?<port>\d+))?$/
|
||||
// a port can be a number or a placeholder string with leading and trailing double underscores, f.e. "8080" or "__PLACEHOLDER_NAME__"
|
||||
const LOCALHOST_REGEX = /^((?<protocol>http[s]?):\/\/)?(?<host>localhost)(:(?<port>(\d+|__\w+__)))?$/
|
||||
|
||||
/**
|
||||
* `backendUrl` should now be used only when self-hosting
|
||||
|
||||
@@ -62,5 +62,21 @@ describe('urlFromParams', () => {
|
||||
expect(url).toBe('http://localhost:2001/v1/auth')
|
||||
})
|
||||
})
|
||||
|
||||
describe('"localhost" with a placeholder for custom port', () => {
|
||||
it('should use the specified placeholder and return "http://localhost:__FOO_BAR__/v1/auth"', async () => {
|
||||
const url = urlFromSubdomain({ subdomain: 'localhost:__FOO_BAR__' }, 'auth')
|
||||
|
||||
expect(url).toBe('http://localhost:__FOO_BAR__/v1/auth')
|
||||
})
|
||||
})
|
||||
|
||||
describe('"localhost" with invalid custom port', () => {
|
||||
it('should throw an error"', async () => {
|
||||
expect(() => {
|
||||
urlFromSubdomain({ subdomain: 'localhost:_invalid_FOO_BAR__' }, 'auth')
|
||||
}).toThrow()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user