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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ test/fixtures/components/welcome-with-optional-parameters/_package

logintervals.md
dist/
test-components/
10 changes: 5 additions & 5 deletions src/cli/domain/get-mocked-plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import fs from 'fs-extra';

import strings from '../../resources/';
import settings from '../../resources/settings';
import type { OcJsonConfig } from '../../types';
import type { Logger } from '../logger';
import { getOcConfig } from './ocConfig';

interface MockedPlugin {
register: (options: unknown, dependencies: unknown, next: () => void) => void;
Expand Down Expand Up @@ -134,22 +134,22 @@ export default function getMockedPlugins(
return plugins;
}

const content: OcJsonConfig = fs.readJsonSync(ocJsonPath);
const content = getOcConfig(ocJsonPath);
const ocJsonLocation = ocJsonPath.slice(0, -ocJsonFileName.length);

if (!content.mocks || !content.mocks.plugins) {
if (!content.development?.plugins) {
return plugins;
}

logger.warn(strings.messages.cli.REGISTERING_MOCKED_PLUGINS);

plugins = plugins.concat(
registerStaticMocks(content.mocks.plugins.static ?? {}, logger)
registerStaticMocks(content.development.plugins.static ?? {}, logger)
);
plugins = plugins.concat(
registerDynamicMocks(
ocJsonLocation,
content.mocks.plugins.dynamic ?? {},
content.development.plugins.dynamic ?? {},
logger
)
);
Expand Down
29 changes: 11 additions & 18 deletions src/cli/domain/mock.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
import path from 'node:path';
import fs from 'fs-extra';

import settings from '../../resources/settings';
import { getOcConfig, setOcConfig } from './ocConfig';

export default function mock() {
return async (params: {
targetType: string;
targetType: 'plugin';
targetValue: string;
targetName: string;
}): Promise<void> => {
const localConfig = await fs
.readJson(settings.configFile.src)
.catch(() => ({}));

const mockType = params.targetType + 's';
const localConfig = getOcConfig();

if (!localConfig.mocks) {
localConfig.mocks = {};
}
const mockType = `${params.targetType}s` as const;

if (!localConfig.mocks[mockType]) {
localConfig.mocks[mockType] = {};
if (!localConfig.development[mockType]) {
localConfig.development[mockType] = {};
}

let pluginType = 'static';
let pluginType: 'static' | 'dynamic' = 'static';
if (fs.existsSync(path.resolve(params.targetValue.toString()))) {
pluginType = 'dynamic';
}

if (!localConfig.mocks[mockType][pluginType]) {
localConfig.mocks[mockType][pluginType] = {};
if (!localConfig.development[mockType][pluginType]) {
localConfig.development[mockType][pluginType] = {};
}

localConfig.mocks[mockType][pluginType][params.targetName] =
localConfig.development[mockType][pluginType]![params.targetName] =
params.targetValue;

return fs.writeJson(settings.configFile.src, localConfig, { spaces: 2 });
return setOcConfig(localConfig);
};
}
92 changes: 92 additions & 0 deletions src/cli/domain/ocConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import fs from 'node:fs';
import settings from '../../resources/settings';

export interface OpenComponentsConfig {
/** JSON schema specification reference */
$schema?: string | null;
/** List of registry URLs where components will be published */
registries?: string[];
/** Development-specific configuration settings */
development?: {
/** Fallback configuration for when components cannot be found locally */
fallback?: {
/** URL of the fallback registry to use when components cannot be found locally */
url: string;
/** Whether to use the fallback registry's oc-client-browser.js for previewing components */
client?: boolean;
};

/** Plugin mocking configuration for development */
plugins?: {
/** Dynamic plugin mocks - file paths to JavaScript modules */
dynamic?: Record<string, string>;
/** Static plugin mocks - static values that will always be returned */
static?: Record<string, string>;
};
};
/** @deprecated Use development.plugins instead */
mocks?: {
/** @deprecated Use development.plugins instead */
plugins?: {
/** @deprecated Use development.plugins.dynamic instead */
dynamic?: Record<string, string>;
/** @deprecated Use development.plugins.static instead */
static?: Record<string, string>;
};
};
}

type ParsedConfig = {
registries: string[];
development: {
plugins: {
dynamic?: Record<string, string>;
static?: Record<string, string>;
};
fallback?: {
url: string;
client?: boolean;
};
};
};

function parseConfig(config: OpenComponentsConfig): ParsedConfig {
const plugins = {
...(config.mocks?.plugins || {}),
...(config.development?.plugins || {})
};

const parsedConfig: ParsedConfig = {
...config,
registries: config.registries || [],
development: {
plugins,
fallback: config.development?.fallback
}
};

return parsedConfig;
}

export function getOcConfig(path?: string): ParsedConfig {
try {
const config = JSON.parse(
fs.readFileSync(path || settings.configFile.src, 'utf8')
);
return parseConfig(config);
} catch {
return {
registries: [],
development: {
plugins: {}
}
};
}
}

export function setOcConfig(config: ParsedConfig, path?: string) {
fs.writeFileSync(
path || settings.configFile.src,
JSON.stringify(parseConfig(config), null, 2)
);
}
1 change: 1 addition & 0 deletions src/cli/domain/package-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const packageComponents =
production
};

console.log('compiling component', componentPath);
const ocTemplate = requireTemplate(type, {
compiler: true,
componentPath
Expand Down
17 changes: 7 additions & 10 deletions src/cli/domain/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import settings from '../../resources/settings';
import type { Component } from '../../types';
import put from '../../utils/put';
import * as urlParser from '../domain/url-parser';
import { getOcConfig, setOcConfig } from './ocConfig';

const getOcVersion = (): string => {
const ocPackagePath = path.join(__dirname, '../../../package.json');
Expand Down Expand Up @@ -41,9 +42,7 @@ export default function registry(opts: RegistryOptions = {}) {
if (!apiResponse) throw 'oc registry not available';
if (apiResponse.type !== 'oc-registry') throw 'not a valid oc registry';

const res = await fs
.readJson(settings.configFile.src)
.catch(() => ({}));
const res = getOcConfig();

if (!res.registries) {
res.registries = [];
Expand All @@ -53,7 +52,7 @@ export default function registry(opts: RegistryOptions = {}) {
res.registries.push(registry);
}

return fs.writeJson(settings.configFile.src, res);
return setOcConfig(res);
} catch {
throw 'oc registry not available';
}
Expand All @@ -64,7 +63,7 @@ export default function registry(opts: RegistryOptions = {}) {
}

try {
const res = await fs.readJson(settings.configFile.src);
const res = getOcConfig();

if (!res.registries || res.registries.length === 0)
throw 'No oc registries';
Expand Down Expand Up @@ -135,12 +134,10 @@ export default function registry(opts: RegistryOptions = {}) {
registry += '/';
}

const res: { registries: string[] } = await fs
.readJson(settings.configFile.src)
.catch(() => ({ registries: [] }));
res.registries = res.registries.filter((x) => x !== registry);
const res = getOcConfig();
res.registries = res.registries?.filter((x) => x !== registry) || [];

await fs.writeJson(settings.configFile.src, res);
setOcConfig(res);
}
};
}
Expand Down
22 changes: 21 additions & 1 deletion src/cli/facade/dev.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import path from 'node:path';
import { promisify } from 'node:util';
import colors from 'colors/safe';
import fs from 'fs-extra';
import getPortCb from 'getport';
import livereload from 'livereload';
import { fromPromise } from 'universalify';

import * as oc from '../../index';
import strings from '../../resources/index';
import settings from '../../resources/settings';
import getMockedPlugins from '../domain/get-mocked-plugins';
import handleDependencies from '../domain/handle-dependencies';
import type { Local } from '../domain/local';
Expand Down Expand Up @@ -39,7 +41,24 @@ const dev = ({ local, logger }: { logger: Logger; local: Local }) =>
const componentsDir = opts.dirPath;
const port = opts.port || 3000;
const baseUrl = opts.baseUrl || `http://localhost:${port}/`;
const fallbackRegistryUrl = opts.fallbackRegistryUrl;

let fallbackRegistryUrl = opts.fallbackRegistryUrl;
let fallbackClient = false;
if (!fallbackRegistryUrl) {
try {
const localConfig = await fs.readJson(settings.configFile.src);
if (
!fallbackRegistryUrl &&
typeof localConfig.development?.fallback?.url === 'string'
) {
fallbackRegistryUrl = localConfig.development?.fallback?.url;
}
fallbackClient = !!localConfig.development?.fallback?.client;
} catch {
// Config file doesn't exist or is invalid, continue without fallback
}
}

const hotReloading =
typeof opts.hotReloading === 'undefined' ? true : opts.hotReloading;
const optWatch = typeof opts.watch === 'undefined' ? true : opts.watch;
Expand Down Expand Up @@ -180,6 +199,7 @@ const dev = ({ local, logger }: { logger: Logger; local: Local }) =>
discovery: true,
env: { name: 'local' },
fallbackRegistryUrl,
fallbackClient,
hotReloading,
liveReloadPort: liveReload.port,
local: true,
Expand Down
6 changes: 5 additions & 1 deletion src/cli/facade/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ import type { Logger } from '../logger';
const mock = ({ local, logger }: { local: Local; logger: Logger }) =>
fromPromise(
async (opts: {
targetType: string;
targetType: 'plugin';
targetValue: string;
targetName: string;
}): Promise<void> => {
if (opts.targetType !== 'plugin') {
throw new Error('targetType must be "plugin"');
}

await local.mock(opts);
logger.ok(
strings.messages.cli.MOCKED_PLUGIN(opts.targetName, opts.targetValue)
Expand Down
Loading