Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions graphql/env/__tests__/__snapshots__/merge.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ exports[`getEnvOptions merges pgpm defaults, graphql defaults, config, env, and
],
"isPublic": true,
"metaSchemas": [
"config_meta",
"services_public",
"metaschema_public",
"metaschema_modules_public",
"env_meta1",
"env_meta2",
],
Expand Down Expand Up @@ -75,9 +71,6 @@ exports[`getEnvOptions merges pgpm defaults, graphql defaults, config, env, and
"graphileBuildOptions": {},
"overrideSettings": {},
"schema": [
"config_schema",
"env_schema_a",
"env_schema_b",
"override_schema",
],
},
Expand Down
28 changes: 6 additions & 22 deletions graphql/env/__tests__/merge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ describe('getEnvOptions', () => {
expect(result).toMatchSnapshot();
});

it('dedupes graphql array fields across config, env, and overrides', () => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'graphql-env-dedupe-'));
it('replaces graphql array fields with later values (overrides win)', () => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'graphql-env-replace-'));
writeConfig(tempDir, {
graphile: {
schema: ['config_schema', 'shared_schema']
Expand Down Expand Up @@ -116,25 +116,9 @@ describe('getEnvOptions', () => {
testEnv
);

expect(result.graphile?.schema).toEqual([
'config_schema',
'shared_schema',
'env_schema',
'override_schema'
]);
expect(result.api?.exposedSchemas).toEqual([
'public',
'shared',
'env_schema',
'override_schema'
]);
expect(result.api?.metaSchemas).toEqual([
'metaschema_public',
'services_public',
'config_meta',
'metaschema_modules_public',
'env_meta',
'override_meta'
]);
// Arrays are replaced, not merged - overrides win completely
expect(result.graphile?.schema).toEqual(['override_schema', 'shared_schema']);
expect(result.api?.exposedSchemas).toEqual(['public', 'override_schema']);
expect(result.api?.metaSchemas).toEqual(['env_meta', 'override_meta']);
});
});
4 changes: 2 additions & 2 deletions graphql/env/src/merge.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import deepmerge from 'deepmerge';
import { ConstructiveOptions, constructiveGraphqlDefaults } from '@constructive-io/graphql-types';
import { getEnvOptions as getPgpmEnvOptions, loadConfigSync, mergeArraysUnique } from '@pgpmjs/env';
import { getEnvOptions as getPgpmEnvOptions, loadConfigSync, replaceArrays } from '@pgpmjs/env';
import { getGraphQLEnvVars } from './env';

/**
Expand Down Expand Up @@ -47,7 +47,7 @@ export const getEnvOptions = (
graphqlEnvOptions,
overrides
], {
arrayMerge: mergeArraysUnique
arrayMerge: replaceArrays
}) as ConstructiveOptions;
};

Expand Down
29 changes: 7 additions & 22 deletions pgpm/env/__tests__/merge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ describe('getEnvOptions', () => {
expect(result).toMatchSnapshot();
});

it('dedupes array fields across config, env, and overrides', () => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pgpm-env-dedupe-'));
it('replaces array fields with later values (overrides win)', () => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pgpm-env-replace-'));
writeConfig(tempDir, {
db: {
extensions: ['uuid', 'postgis']
Expand Down Expand Up @@ -219,25 +219,10 @@ describe('getEnvOptions', () => {

const result = getEnvOptions(overrides, tempDir, testEnv) as PgpmOptionsWithPackages;

expect(result.db?.extensions).toEqual([
'uuid',
'postgis',
'pgcrypto',
'hstore'
]);
expect(result.jobs?.worker?.supported).toEqual([
'alpha',
'beta',
'gamma',
'delta',
'epsilon'
]);
expect(result.jobs?.scheduler?.supported).toEqual([
'beta',
'gamma',
'delta',
'zeta'
]);
expect(result.packages).toEqual(['testing/*', 'packages/*', 'extensions/*']);
// Arrays are replaced, not merged - overrides win completely
expect(result.db?.extensions).toEqual(['uuid', 'hstore']);
expect(result.jobs?.worker?.supported).toEqual(['delta', 'epsilon']);
expect(result.jobs?.scheduler?.supported).toEqual(['gamma', 'zeta']);
expect(result.packages).toEqual(['testing/*', 'extensions/*']);
});
});
2 changes: 1 addition & 1 deletion pgpm/env/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export {
} from './config';
export type { WorkspaceType } from './config';
export { getEnvVars, getNodeEnv, parseEnvBoolean, parseEnvNumber } from './env';
export { walkUp, mergeArraysUnique } from './utils';
export { walkUp, replaceArrays } from './utils';

export type { PgpmOptions, PgTestConnectionOptions, DeploymentOptions } from '@pgpmjs/types';
4 changes: 2 additions & 2 deletions pgpm/env/src/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import deepmerge from 'deepmerge';
import { pgpmDefaults, PgpmOptions, PgTestConnectionOptions, DeploymentOptions } from '@pgpmjs/types';
import { loadConfigSync } from './config';
import { getEnvVars } from './env';
import { mergeArraysUnique } from './utils';
import { replaceArrays } from './utils';

/**
* Get core PGPM environment options by merging:
Expand All @@ -26,7 +26,7 @@ export const getEnvOptions = (
const envOptions = getEnvVars(env);

return deepmerge.all([pgpmDefaults, configOptions, envOptions, overrides], {
arrayMerge: mergeArraysUnique
arrayMerge: replaceArrays
});
};

Expand Down
11 changes: 7 additions & 4 deletions pgpm/env/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@ export const walkUp = (startDir: string, filename: string): string => {
throw new Error(`File "${filename}" not found in any parent directories.`);
};

export const mergeArraysUnique = <T>(
target: T[],
/**
* Array merge strategy that replaces target array with source array.
* This allows later configuration sources to completely override earlier ones.
*/
export const replaceArrays = <T>(
_target: T[],
source: T[],
_options?: unknown
): T[] => {
const merged = [...target, ...source];
return [...new Set(merged)];
return source;
};