0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-03 22:57:08 -05:00
This commit is contained in:
Fred K. Schott 2024-01-24 16:07:17 -08:00
parent bfd2706378
commit 65696de832
9 changed files with 49 additions and 48 deletions

View file

@ -22,10 +22,12 @@ export async function getPackage<T>(
otherDeps: string[] = []
): Promise<T | undefined> {
try {
// Custom resolution logic for @astrojs/db. Since it lives in our monorepo,
// Custom resolution logic for @astrojs/db. Since it lives in our monorepo,
// the generic tryResolve() method doesn't work.
if (packageName === '@astrojs/db') {
const packageJsonLoc = require.resolve(packageName + '/package.json', {paths: [options.cwd ?? process.cwd()]});
const packageJsonLoc = require.resolve(packageName + '/package.json', {
paths: [options.cwd ?? process.cwd()],
});
const packageLoc = packageJsonLoc.replace(`package.json`, 'dist/index.js');
const packageImport = await import(packageLoc);
return packageImport as T;

View file

@ -1,10 +1,7 @@
import type { AstroConfig } from 'astro';
import deepDiff from 'deep-diff';
import type { Arguments } from 'yargs-parser';
import {
getMigrations,
initializeFromMigrations,
} from '../../../migrations.js';
import { getMigrations, initializeFromMigrations } from '../../../migrations.js';
const { diff, applyChange } = deepDiff;
export async function cmd({ config }: { config: AstroConfig; flags: Arguments }) {

View file

@ -18,7 +18,7 @@ export async function cli({ flags, config }: { flags: Arguments; config: AstroCo
return await verifyCommand({ config, flags });
}
default: {
if(command == null) {
if (command == null) {
// eslint-disable-next-line no-console
console.error(`No command provided.
@ -40,6 +40,6 @@ Usage:
astro db sync Creates snapshot based on your schema
astro db push Pushes migrations to Astro Studio
astro db verify Verifies migrations have been pushed and errors if not`
astro db verify Verifies migrations have been pushed and errors if not`;
}
}

View file

@ -41,13 +41,13 @@ export async function getMigrationQueries({
const resolved = await resolveCollectionRenames(
added,
dropped,
promptResponses?.collectionRenames,
promptResponses?.collectionRenames
);
added = resolved.added;
dropped = resolved.dropped;
for (const { from, to } of resolved.renamed) {
const renameQuery = `ALTER TABLE ${sqlite.escapeName(from)} RENAME TO ${sqlite.escapeName(
to,
to
)}`;
queries.push(renameQuery);
}
@ -100,7 +100,7 @@ export async function getCollectionChangeQueries({
collectionName,
added,
dropped,
promptResponses?.fieldRenames,
promptResponses?.fieldRenames
);
added = resolved.added;
dropped = resolved.dropped;
@ -120,26 +120,26 @@ export async function getCollectionChangeQueries({
let allowDataLoss = promptResponses?.allowDataLoss;
const nameMsg = `Type the collection name ${color.blue(
collectionName,
collectionName
)} to confirm you want to delete all data:`;
const { reason, fieldName } = dataLossCheck;
const reasonMsgs: Record<DataLossReason, string> = {
'added-required': `Adding required ${color.blue(
color.bold(collectionName),
color.bold(collectionName)
)} field ${color.blue(color.bold(fieldName))}. ${color.red(
'This will delete all existing data in the collection!',
'This will delete all existing data in the collection!'
)} We recommend setting a default value to avoid data loss.`,
'updated-required': `Changing ${color.blue(color.bold(collectionName))} field ${color.blue(
color.bold(fieldName),
color.bold(fieldName)
)} to required. ${color.red('This will delete all existing data in the collection!')}`,
'updated-unique': `Changing ${color.blue(color.bold(collectionName))} field ${color.blue(
color.bold(fieldName),
color.bold(fieldName)
)} to unique. ${color.red('This will delete all existing data in the collection!')}`,
'updated-type': `Changing the type of ${color.blue(
color.bold(collectionName),
color.bold(collectionName)
)} field ${color.blue(color.bold(fieldName))}. ${color.red(
'This will delete all existing data in the collection!',
'This will delete all existing data in the collection!'
)}`,
};
@ -175,7 +175,7 @@ async function resolveFieldRenames(
collectionName: string,
mightAdd: DBFields,
mightDrop: DBFields,
renamePromptResponses?: PromptResponses['fieldRenames'],
renamePromptResponses?: PromptResponses['fieldRenames']
): Promise<{ added: DBFields; dropped: DBFields; renamed: Renamed }> {
const added: DBFields = {};
const dropped: DBFields = {};
@ -195,7 +195,7 @@ async function resolveFieldRenames(
type: 'toggle',
name: 'isRename',
message: `Is the field ${color.blue(color.bold(fieldName))} in collection ${color.blue(
color.bold(collectionName),
color.bold(collectionName)
)} a new field, or renaming an existing field?`,
initial: false,
active: 'Rename',
@ -215,7 +215,7 @@ async function resolveFieldRenames(
type: 'select',
name: 'oldFieldName',
message: `Which field in ${color.blue(
color.bold(collectionName),
color.bold(collectionName)
)} should be renamed to ${color.blue(color.bold(fieldName))}?`,
choices,
});
@ -223,7 +223,8 @@ async function resolveFieldRenames(
renamed.push({ from: oldFieldName, to: fieldName });
for (const [droppedFieldName, droppedField] of Object.entries(mightDrop)) {
if (!renamed.find((r) => r.from === droppedFieldName)) dropped[droppedFieldName] = droppedField;
if (!renamed.find((r) => r.from === droppedFieldName))
dropped[droppedFieldName] = droppedField;
}
}
@ -233,7 +234,7 @@ async function resolveFieldRenames(
async function resolveCollectionRenames(
mightAdd: DBCollections,
mightDrop: DBCollections,
renamePromptResponses?: PromptResponses['fieldRenames'],
renamePromptResponses?: PromptResponses['fieldRenames']
): Promise<{ added: DBCollections; dropped: DBCollections; renamed: Renamed }> {
const added: DBCollections = {};
const dropped: DBCollections = {};
@ -253,7 +254,7 @@ async function resolveCollectionRenames(
type: 'toggle',
name: 'isRename',
message: `Is the collection ${color.blue(
color.bold(collectionName),
color.bold(collectionName)
)} a new collection, or renaming an existing collection?`,
initial: false,
active: 'Rename',
@ -279,7 +280,8 @@ async function resolveCollectionRenames(
renamed.push({ from: oldCollectionName, to: collectionName });
for (const [droppedCollectionName, droppedCollection] of Object.entries(mightDrop)) {
if (!renamed.find((r) => r.from === droppedCollectionName)) dropped[droppedCollectionName] = droppedCollection;
if (!renamed.find((r) => r.from === droppedCollectionName))
dropped[droppedCollectionName] = droppedCollection;
}
}
@ -308,7 +310,7 @@ function getFieldRenameQueries(unescCollectionName: string, renamed: Renamed): s
for (const { from, to } of renamed) {
const q = `ALTER TABLE ${collectionName} RENAME COLUMN ${sqlite.escapeName(
from,
from
)} TO ${sqlite.escapeName(to)}`;
queries.push(q);
}
@ -323,7 +325,7 @@ function getFieldRenameQueries(unescCollectionName: string, renamed: Renamed): s
function getAlterTableQueries(
unescCollectionName: string,
added: DBFields,
dropped: DBFields,
dropped: DBFields
): string[] {
const queries: string[] = [];
const collectionName = sqlite.escapeName(unescCollectionName);
@ -333,7 +335,7 @@ function getAlterTableQueries(
const type = schemaTypeToSqlType(field.type);
const q = `ALTER TABLE ${collectionName} ADD COLUMN ${fieldName} ${type}${getModifiers(
fieldName,
field,
field
)}`;
queries.push(q);
}
@ -369,7 +371,7 @@ function getRecreateTableQueries({
const escapedColumns = originalColumns.map((c) => sqlite.escapeName(c)).join(', ');
queries.push(
`INSERT INTO ${tempName} (${escapedColumns}) SELECT ${escapedColumns} FROM ${collectionName}`,
`INSERT INTO ${tempName} (${escapedColumns}) SELECT ${escapedColumns} FROM ${collectionName}`
);
}
@ -384,7 +386,7 @@ export function getCreateTableQuery(collectionName: string, collection: DBCollec
const colQueries = ['"id" text PRIMARY KEY'];
for (const [columnName, column] of Object.entries(collection.fields)) {
const colQuery = `${sqlite.escapeName(columnName)} ${schemaTypeToSqlType(
column.type,
column.type
)}${getModifiers(columnName, column)}`;
colQueries.push(colQuery);
}
@ -448,7 +450,7 @@ type DataLossResponse =
function canRecreateTableWithoutDataLoss(
added: DBFields,
updated: UpdatedFields,
updated: UpdatedFields
): DataLossResponse {
for (const [fieldName, a] of Object.entries(added)) {
if (!a.optional && !hasDefault(a))
@ -519,7 +521,7 @@ const typeChangesWithoutQuery: Array<{ from: FieldType; to: FieldType }> = [
function canChangeTypeWithoutQuery(oldField: DBField, newField: DBField) {
return typeChangesWithoutQuery.some(
({ from, to }) => oldField.type === from && newField.type === to,
({ from, to }) => oldField.type === from && newField.type === to
);
}
@ -560,8 +562,8 @@ function getDefaultValueSql(columnName: string, column: DBFieldWithDefault): str
// eslint-disable-next-line no-console
console.log(
`Invalid default value for column ${color.bold(
columnName,
)}. Defaults must be valid JSON when using the \`json()\` type.`,
columnName
)}. Defaults must be valid JSON when using the \`json()\` type.`
);
process.exit(0);
}

View file

@ -37,7 +37,7 @@ export const errorMap: z.ZodErrorMap = (baseError, ctx) => {
const messages: string[] = [
prefix(
baseErrorPath,
typeOrLiteralErrByPath.size ? 'Did not match union:' : 'Did not match union.',
typeOrLiteralErrByPath.size ? 'Did not match union:' : 'Did not match union.'
),
];
return {
@ -51,8 +51,8 @@ export const errorMap: z.ZodErrorMap = (baseError, ctx) => {
// Avoid printing the key again if it's a base error
key === baseErrorPath
? `> ${getTypeOrLiteralMsg(error)}`
: `> ${prefix(key, getTypeOrLiteralMsg(error))}`,
),
: `> ${prefix(key, getTypeOrLiteralMsg(error))}`
)
)
.join('\n'),
};
@ -65,7 +65,7 @@ export const errorMap: z.ZodErrorMap = (baseError, ctx) => {
code: baseError.code,
received: (baseError as any).received,
expected: [baseError.expected],
}),
})
),
};
} else if (baseError.message) {
@ -81,11 +81,11 @@ const getTypeOrLiteralMsg = (error: TypeOrLiteralErrByPathEntry): string => {
switch (error.code) {
case 'invalid_type':
return `Expected type \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
error.received,
error.received
)}`;
case 'invalid_literal':
return `Expected \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
error.received,
error.received
)}`;
}
};

View file

@ -1,11 +1,11 @@
import { red } from 'kleur/colors';
export const unexpectedAstroAdminError = `${red(
'Unexpected response from Astro Studio servers.',
'Unexpected response from Astro Studio servers.'
)} Try updating your package version. If the problem persists, please contact support.`;
export const authenticationError = `${red(
'⚠️ Login session invalid or expired.',
'⚠️ Login session invalid or expired.'
)} Please run \`astro login\` again.`;
export const appTokenError = `${red(
'⚠️ App token invalid or expired.',
'⚠️ App token invalid or expired.'
)} Please generate a new one from your the Studio dashboard under project settings.`;

View file

@ -26,7 +26,9 @@ export async function initializeMigrationsDirectory(currentSnapshot: unknown) {
await writeFile('./migrations/0000_snapshot.json', JSON.stringify(currentSnapshot, undefined, 2));
}
export async function initializeFromMigrations(allMigrationFiles: string[]): Promise<DBCollections> {
export async function initializeFromMigrations(
allMigrationFiles: string[]
): Promise<DBCollections> {
const prevSnapshot = await loadInitialSnapshot();
for (const migration of allMigrationFiles) {
if (migration === '0000_snapshot.json') continue;

View file

@ -1,11 +1,10 @@
import type { InStatement } from "@libsql/client";
import type { InStatement } from '@libsql/client';
import type { AstroConfig } from 'astro';
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import { drizzle } from 'drizzle-orm/sqlite-proxy';
import { loadEnv } from 'vite';
import { z } from 'zod';
export type VitePlugin = Required<AstroConfig['vite']>['plugins'][number];
export const STUDIO_ADMIN_TABLE = 'ReservedAstroStudioAdmin';
@ -16,7 +15,6 @@ export const adminTable = sqliteTable(STUDIO_ADMIN_TABLE, {
collections: text('collections').notNull(),
});
export const STUDIO_MIGRATIONS_TABLE = 'ReservedAstroStudioMigrations';
export const migrationsTable = sqliteTable(STUDIO_MIGRATIONS_TABLE, {

View file

@ -9,7 +9,7 @@ describe('astro:db', () => {
fixture = await loadFixture({
root: new URL('./fixtures/basics/', import.meta.url),
output: 'server',
adapter: testAdapter()
adapter: testAdapter(),
});
});