Skip to content

Commit

Permalink
feat: Added ability to specify SSR specific props for apps (#266)
Browse files Browse the repository at this point in the history
* chore: migrations added

* chore: Added ssrProps support in Registry (w/o API and UI) and ILC

* chore: ssrProps added to Registry API

* chore: ssrProps added to Registry UI
  • Loading branch information
StyleT committed Mar 1, 2021
1 parent 5c67b9f commit df50c46
Show file tree
Hide file tree
Showing 16 changed files with 71 additions and 13 deletions.
6 changes: 5 additions & 1 deletion ilc/server/tailor/server-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ module.exports = class ServerRouter {
}
}

ssrOpts.appProps = deepmerge(appInfo.props || {}, row.props || {});
ssrOpts.appProps = deepmerge.all([
appInfo.props || {},
appInfo.ssrProps || {},
row.props || {}
]);
ssrOpts.wrapperConf = row.wrapperConf;

res[appId] = ssrOpts;
Expand Down
1 change: 1 addition & 0 deletions registry/client/src/apps/Edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ const InputForm = ({mode = 'edit', ...props}) => {
</FormTab>
<FormTab label="Props">
<JsonField source="props" label="Properties that will be passed to application" />
<JsonField source="ssrProps" label="Properties that will be added to main props at SSR request, allow to override certain values" />
</FormTab>
</TabbedForm>
);
Expand Down
8 changes: 7 additions & 1 deletion registry/client/src/apps/dataTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ export function transformGet(app) {
if (app.props) {
app.props = JSON.stringify(app.props);
}
if (app.ssrProps) {
app.ssrProps = JSON.stringify(app.ssrProps);
}
}

export function transformSet(app) {
if (app.props) {
if (app.props && typeof data.props === 'string') {
app.props = JSON.parse(app.props);
}
if (app.ssrProps && typeof data.ssrProps === 'string') {
app.ssrProps = JSON.parse(app.ssrProps);
}
if (app.dependencies) {
app.dependencies = app.dependencies.reduce((acc, v) => {
acc[v.key] = v.value;
Expand Down
3 changes: 2 additions & 1 deletion registry/client/src/sharedProps/Edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const InputForm = ({mode = 'edit', ...props}) => {
{mode === 'edit'
? <TextField source="name" />
: <TextInput source="name" fullWidth validate={required()} />}
<JsonField source="props"/>
<JsonField source="props" label="Properties that will be passed to applications"/>
<JsonField source="ssrProps" label="Properties that will be added to main props at SSR request, allow to override certain values" />
</SimpleForm>
);
};
Expand Down
8 changes: 7 additions & 1 deletion registry/client/src/sharedProps/dataTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ export function transformGet(data) {
if (data.props) {
data.props = JSON.stringify(data.props);
}
if (data.ssrProps) {
data.ssrProps = JSON.stringify(data.ssrProps);
}
}

export function transformSet(data) {
if (data.props) {
if (data.props && typeof data.props === 'string') {
data.props = JSON.parse(data.props);
}
if (data.ssrProps && typeof data.ssrProps === 'string') {
data.ssrProps = JSON.parse(data.ssrProps);
}
delete data.id;
}
2 changes: 2 additions & 0 deletions registry/server/apps/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default interface App {
assetsDiscoveryUrl?: string,
dependencies?: string, // JSON({ [packageName: string]: string })
props?: string, // JSON({ [propName: string]: any })
ssrProps?: string, // JSON({ [propName: string]: any })
configSelector?: string,
ssr: string, // JSON({ src: string, timeout: number })
wrappedWith?: string,
Expand All @@ -26,6 +27,7 @@ const commonApp = {
assetsDiscoveryUrl: Joi.string().trim().uri().default(null),
dependencies: Joi.object().default({}),
props: Joi.object().default({}),
ssrProps: Joi.object().default({}),
configSelector: Joi.array().items(Joi.string()).default([]),
ssr: Joi.object({
src: Joi.string().trim().uri(),
Expand Down
2 changes: 1 addition & 1 deletion registry/server/apps/routes/createApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const createApp = async (req: Request, res: Response): Promise<void> => {

await db.versioning(req.user, {type: 'apps', id: app.name}, async (trx) => {
await db('apps')
.insert(stringifyJSON(['dependencies', 'props', 'ssr', 'configSelector'], app))
.insert(stringifyJSON(['dependencies', 'props', 'ssrProps', 'ssr', 'configSelector'], app))
.transacting(trx);
});

Expand Down
2 changes: 1 addition & 1 deletion registry/server/apps/routes/updateApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const updateApp = async (req: Request<UpdateAppRequestParams>, res: Response): P
await db.versioning(req.user, {type: 'apps', id: appName}, async (trx) => {
await db('apps')
.where({ name: appName })
.update(stringifyJSON(['dependencies', 'props', 'ssr', 'configSelector'], app))
.update(stringifyJSON(['dependencies', 'props', 'ssrProps', 'ssr', 'configSelector'], app))
.transacting(trx);
});

Expand Down
16 changes: 16 additions & 0 deletions registry/server/migrations/20210226191151_apps_ssrProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as Knex from "knex";


export async function up(knex: Knex): Promise<void> {
return knex.schema.table('apps', table => {
table.json('ssrProps');
});
}


export async function down(knex: Knex): Promise<void> {
return knex.schema.table('apps', table => {
table.dropColumn('ssrProps');
});
}

16 changes: 16 additions & 0 deletions registry/server/migrations/20210226191205_shared_props_ssrProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as Knex from "knex";


export async function up(knex: Knex): Promise<void> {
return knex.schema.table('shared_props', table => {
table.json('ssrProps');
});
}


export async function down(knex: Knex): Promise<void> {
return knex.schema.table('shared_props', table => {
table.dropColumn('ssrProps');
});
}

4 changes: 3 additions & 1 deletion registry/server/routes/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ router.get('/', async (req, res) => {
v.ssr = JSON.parse(v.ssr);
v.dependencies = JSON.parse(v.dependencies);
v.props = JSON.parse(v.props);
v.ssrProps = JSON.parse(v.ssrProps);
if (sharedProps.length && v.configSelector !== null) {
JSON.parse(v.configSelector).forEach((configSelectorName: string) => {
const commonConfig = sharedProps.find(n => n.name === configSelectorName);
if (commonConfig) {
v.props = _.merge({}, JSON.parse(commonConfig.props), v.props);
v.ssrProps = _.merge({}, JSON.parse(commonConfig.ssrProps), v.ssrProps);
}
});
}

v = _.omitBy(v, v => v === null || (typeof v === 'object' && Object.keys(v).length === 0));
acc[v.name] = _.pick(v, ['kind', 'ssr', 'dependencies', 'props', 'spaBundle', 'cssBundle', 'wrappedWith']);
acc[v.name] = _.pick(v, ['kind', 'ssr', 'dependencies', 'props', 'ssrProps', 'spaBundle', 'cssBundle', 'wrappedWith']);

return acc;
}, {});
Expand Down
3 changes: 2 additions & 1 deletion registry/server/sharedProps/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export default interface SharedProps {
export const sharedPropsNameSchema = Joi.string().min(1).max(50);

const commonSharedProps = {
props: Joi.object(),
props: Joi.object().default({}),
ssrProps: Joi.object().default({}),
};

export const partialSharedPropsSchema = Joi.object({
Expand Down
2 changes: 1 addition & 1 deletion registry/server/sharedProps/routes/createSharedProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const createSharedProps = async (req: Request, res: Response): Promise<void> =>
const sharedProps = req.body;

await db.versioning(req.user, {type: 'shared_props', id: sharedProps.name}, async (trx) => {
await db('shared_props').insert(stringifyJSON(['props'], sharedProps)).transacting(trx);
await db('shared_props').insert(stringifyJSON(['props', 'ssrProps'], sharedProps)).transacting(trx);
});

const [savedSharedProps] = await db.select().from<SharedProps>('shared_props').where('name', sharedProps.name);
Expand Down
2 changes: 1 addition & 1 deletion registry/server/sharedProps/routes/updateSharedProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const updateSharedProps = async (req: Request<RequestParams>, res: Response): Pr
await db.versioning(req.user, {type: 'shared_props', id: sharedPropsName}, async (trx) => {
await db('shared_props')
.where({ name: sharedPropsName })
.update(stringifyJSON(['props'], sharedProps))
.update(stringifyJSON(['props', 'ssrProps'], sharedProps))
.transacting(trx);
});

Expand Down
7 changes: 5 additions & 2 deletions registry/tests/sharedProps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const example = {
name: 'ncTestSharedPropsName',
props: {
ncTestSharedPropsPropName: 'ncTestSharedPropsPropValue',
},
ssrProps: {
testSsrOnly: 'value'
}
}),
updated: Object.freeze({
Expand All @@ -31,11 +34,11 @@ describe(`Tests ${example.url}`, () => {
props: 456
};

let response = await request.post(example.url)
await request.post(example.url)
.send(incorrect)
.expect(422, '"props" must be of type object\n"name" must be a string');

response = await request.get(example.url + incorrect.name)
await request.get(example.url + incorrect.name)
.expect(404, 'Not found');
});

Expand Down
2 changes: 1 addition & 1 deletion registry/tests/versioning.unit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('Versioning Unit', () => {
expect(changeData.entity_type).to.equal(entityType);
expect(changeData.entity_id).to.equal(entityId);
expect(changeData.data).to.be.null;
expect(changeData.data_after).to.equal('{"data":{"props":"{\\"a\\":1}"},"related":{}}');
expect(changeData.data_after).to.equal('{"data":{"props":"{\\"a\\":1}","ssrProps":null},"related":{}}');
expect(changeData.created_by).to.equal(testUser.identifier);
});

Expand Down

0 comments on commit df50c46

Please sign in to comment.