-
Notifications
You must be signed in to change notification settings - Fork 277
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[XM Cloud][Next.js] Editing Configuration Endpoint (#1724)
* add config api route in xmcloud addon * add generate metadata script to xmcloud addon * add editing config middleware; add generate-metadata in nextjs scripts; modify component builder codegen to export components * update response when unauthorized * move editing-config-middleware from middleware to editing * add unit testsfor editing config middleware; remove base middleware inheritance * remove unused file * update changelog * fix lint error * fix linting errors * minor changelog update * add appropriate descriptions to editing config middleware * reafactoring - move the package metadata logic in the devtools package * export metadata, remove console logs * add unit tests * revert misformated changelog * update generate component builder unit tests * extract Metadata interface in the base package and all necesarry updates around that * fix linting errors
- Loading branch information
Showing
15 changed files
with
423 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/pages/api/editing/config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { EditingConfigMiddleware } from '@sitecore-jss/sitecore-jss-nextjs/editing'; | ||
import { components } from 'temp/componentBuilder'; | ||
import metadata from 'temp/metadata.json'; | ||
|
||
/** | ||
* This Next.js API route is used by Sitecore editors (Pages) in XM Cloud | ||
* to determine feature compatibility and configuration. | ||
*/ | ||
|
||
const handler = new EditingConfigMiddleware({ | ||
components, | ||
metadata, | ||
}).getHandler(); | ||
|
||
export default handler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-metadata.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import { Metadata, getMetadata } from '@sitecore-jss/sitecore-jss-dev-tools'; | ||
|
||
/* | ||
METADATA GENERATION | ||
Generates the /src/temp/metadata.json file which contains application | ||
configuration metadata that is used for Sitecore XM Cloud integration. | ||
*/ | ||
generateMetadata(); | ||
|
||
function generateMetadata(): void { | ||
const metadata: Metadata = getMetadata(); | ||
writeMetadata(metadata); | ||
} | ||
|
||
/** | ||
* Writes the metadata object to disk. | ||
* @param {Metadata} metadata metadata to write. | ||
*/ | ||
function writeMetadata(metadata: Metadata): void { | ||
const filePath = path.resolve('src/temp/metadata.json'); | ||
console.log(`Writing metadata to ${filePath}`); | ||
fs.writeFileSync(filePath, JSON.stringify(metadata, null, 2), { encoding: 'utf8' }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
packages/sitecore-jss-dev-tools/src/templating/metadata.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* eslint-disable quotes */ | ||
/* eslint-disable no-unused-expressions */ | ||
import { expect } from 'chai'; | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import { getMetadata } from './metadata'; | ||
import sinon, { SinonStub } from 'sinon'; | ||
import { Metadata } from '@sitecore-jss/sitecore-jss/utils'; | ||
|
||
describe('metadata', () => { | ||
afterEach(() => { | ||
sinon.restore(); | ||
}); | ||
|
||
describe('getMetadata', () => { | ||
let readdirSync: SinonStub; | ||
let readFileSync: SinonStub; | ||
|
||
afterEach(() => { | ||
readdirSync?.restore(); | ||
readFileSync?.restore(); | ||
}); | ||
|
||
it('should return packages metadata from @sitecore scope', () => { | ||
readdirSync = sinon.stub(fs, 'readdirSync'); | ||
readdirSync.withArgs('node_modules').returns(['@sitecore']); | ||
readdirSync.withArgs(path.join('node_modules', '@sitecore')).returns(['byoc', 'components']); | ||
|
||
readFileSync = sinon.stub(fs, 'readFileSync'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore', 'byoc', 'package.json')) | ||
.returns('{"name": "@sitecore/byoc","version": "0.2.8"}'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore', 'components', 'package.json')) | ||
.returns('{"name": "@sitecore/components","version": "1.1.6"}'); | ||
|
||
const expected: Metadata = { | ||
packages: { | ||
'@sitecore/byoc': '0.2.8', | ||
'@sitecore/components': '1.1.6', | ||
}, | ||
}; | ||
|
||
const packagesMetadata = getMetadata(); | ||
expect(packagesMetadata).to.deep.equal(expected); | ||
}); | ||
|
||
it('should return packages metadata from @sitecore-jss scope', () => { | ||
readdirSync = sinon.stub(fs, 'readdirSync'); | ||
readdirSync.withArgs('node_modules').returns(['@sitecore-jss']); | ||
readdirSync | ||
.withArgs(path.join('node_modules', '@sitecore-jss')) | ||
.returns(['sitecore-jss-cli', 'sitecore-jss-nextjs']); | ||
|
||
readFileSync = sinon.stub(fs, 'readFileSync'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore-jss', 'sitecore-jss-cli', 'package.json')) | ||
.returns('{"name": "@sitecore-jss/sitecore-jss-cli","version": "21.7.0-canary.55"}'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore-jss', 'sitecore-jss-nextjs', 'package.json')) | ||
.returns('{"name": "@sitecore-jss/sitecore-jss-nextjs","version": "21.7.0-canary.55"}'); | ||
|
||
const expected: Metadata = { | ||
packages: { | ||
'@sitecore-jss/sitecore-jss-cli': '21.7.0-canary.55', | ||
'@sitecore-jss/sitecore-jss-nextjs': '21.7.0-canary.55', | ||
}, | ||
}; | ||
|
||
const packagesMetadata = getMetadata(); | ||
expect(packagesMetadata).to.deep.equal(expected); | ||
}); | ||
|
||
it('should return packages metadata from @sitecore-cloudsdk scope', () => { | ||
readdirSync = sinon.stub(fs, 'readdirSync'); | ||
readdirSync.withArgs('node_modules').returns(['@sitecore-cloudsdk']); | ||
readdirSync.withArgs(path.join('node_modules', '@sitecore-cloudsdk')).returns(['core']); | ||
|
||
readFileSync = sinon.stub(fs, 'readFileSync'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore-cloudsdk', 'core', 'package.json')) | ||
.returns('{"name": "@sitecore-cloudsdk/core","version": "0.1.5"}'); | ||
|
||
const expected: Metadata = { | ||
packages: { | ||
'@sitecore-cloudsdk/core': '0.1.5', | ||
}, | ||
}; | ||
|
||
const packagesMetadata = getMetadata(); | ||
expect(packagesMetadata).to.deep.equal(expected); | ||
}); | ||
|
||
it('should return packages metadata from @sitecore-feaas scope', () => { | ||
readdirSync = sinon.stub(fs, 'readdirSync'); | ||
readdirSync.withArgs('node_modules').returns(['@sitecore-feaas']); | ||
readdirSync.withArgs(path.join('node_modules', '@sitecore-feaas')).returns(['clientside']); | ||
|
||
readFileSync = sinon.stub(fs, 'readFileSync'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore-feaas', 'clientside', 'package.json')) | ||
.returns('{"name": "@sitecore-feaas/clientside","version": "0.5.12"}'); | ||
|
||
const expected: Metadata = { | ||
packages: { | ||
'@sitecore-feaas/clientside': '0.5.12', | ||
}, | ||
}; | ||
|
||
const packagesMetadata = getMetadata(); | ||
expect(packagesMetadata).to.deep.equal(expected); | ||
}); | ||
|
||
it('should not return packages metadata for not tracked scopes', () => { | ||
const scope = '@nottracked-scope'; | ||
readdirSync = sinon.stub(fs, 'readdirSync'); | ||
readdirSync.withArgs('node_modules').returns([scope]); | ||
|
||
const expected: Metadata = { packages: {} }; | ||
|
||
const packagesMetadata = getMetadata(); | ||
expect(packagesMetadata).to.deep.equal(expected); | ||
}); | ||
|
||
it('should throw if package.json not found', () => { | ||
readdirSync = sinon.stub(fs, 'readdirSync'); | ||
readdirSync.withArgs('node_modules').returns(['@sitecore-feaas']); | ||
readdirSync.withArgs(path.join('node_modules', '@sitecore-feaas')).returns(['clientside']); | ||
|
||
readFileSync = sinon.stub(fs, 'readFileSync'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore-feaas', 'clientside', 'package.json')) | ||
.returns(null); | ||
|
||
expect(() => getMetadata()).to.throw; | ||
}); | ||
|
||
it('should throw if json not valid', () => { | ||
readdirSync = sinon.stub(fs, 'readdirSync'); | ||
readdirSync.withArgs('node_modules').returns(['@sitecore-feaas']); | ||
readdirSync.withArgs(path.join('node_modules', '@sitecore-feaas')).returns(['clientside']); | ||
|
||
readFileSync = sinon.stub(fs, 'readFileSync'); | ||
readFileSync | ||
.withArgs(path.join('node_modules', '@sitecore-feaas', 'clientside', 'package.json')) | ||
.returns('{"name": "@sitecore-feaas/clientside","version": "0.5.12"'); | ||
|
||
expect(() => getMetadata()).to.throw; | ||
}); | ||
}); | ||
}); |
31 changes: 31 additions & 0 deletions
31
packages/sitecore-jss-dev-tools/src/templating/metadata.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import { Metadata } from '@sitecore-jss/sitecore-jss/utils'; | ||
|
||
/** | ||
* Get application metadata | ||
*/ | ||
export function getMetadata(): Metadata { | ||
const metadata: Metadata = { packages: {} }; | ||
const trackedScopes = ['@sitecore', '@sitecore-cloudsdk', '@sitecore-feaas', '@sitecore-jss']; | ||
const dirs = fs.readdirSync('node_modules'); | ||
|
||
dirs.forEach((dir: any) => { | ||
if (trackedScopes.includes(dir)) { | ||
const packageNames = fs.readdirSync(path.join('node_modules', dir)); | ||
packageNames.forEach((pkg: any) => { | ||
try { | ||
const json = JSON.parse( | ||
fs.readFileSync(path.join('node_modules', dir, pkg, 'package.json'), 'utf8') | ||
); | ||
|
||
metadata.packages[json.name] = json.version; | ||
} catch (e) { | ||
console.error(`Failed to read/parse package.json for ${pkg}`, e); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
return metadata; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.