-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue #SB-28710 fix: Publishing as NG module - sunbird-epub-player
- Loading branch information
1 parent
066b9c6
commit eed89d1
Showing
13 changed files
with
407 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", | ||
"schematics": { | ||
"ng-add": { | ||
"description": "Add @project-sunbird/sunbird-epub-player-v9 to the project.", | ||
"factory": "./ng-add/index", | ||
"schema": "./ng-add/schema.json", | ||
"aliases": ["install"] | ||
}, | ||
"ng-add-setup-project": { | ||
"private": true, | ||
"description": "Sets up the specified project after the ng-add dependencies have been installed.", | ||
"factory": "./ng-add/setup-project", | ||
"schema": "./ng-add/schema.json" | ||
} | ||
} | ||
} | ||
|
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,53 @@ | ||
import {Rule, SchematicContext, SchematicsException, Tree} from '@angular-devkit/schematics'; | ||
import { | ||
NodePackageInstallTask, | ||
RunSchematicTask, | ||
} from '@angular-devkit/schematics/tasks'; | ||
|
||
import {getWorkspace} from '@schematics/angular/utility/workspace'; | ||
|
||
import {Schema} from './schema'; | ||
import * as messages from './messages'; | ||
import {addPackageToPackageJson} from '../utils/package-config'; | ||
|
||
interface VersionOptions { | ||
[key: string]: string; | ||
} | ||
|
||
const VERSIONS: VersionOptions = { | ||
// automatically filled from package.json during the build | ||
'@project-sunbird/sb-styles': '0.0.7', | ||
'@project-sunbird/client-services': '^3.4.8', | ||
epubjs: '0.3.88', | ||
}; | ||
|
||
/** | ||
* This is executed when `ng add @project-sunbird/sunbird-epub-player-v9` is run. | ||
* It installs all dependencies in the 'package.json' and runs 'ng-add-setup-project' schematic. | ||
*/ | ||
export default function ngAdd(options: Schema): Rule { | ||
return async (tree: Tree, context: SchematicContext) => { | ||
|
||
// Checking that project exists | ||
const {project} = options; | ||
if (project) { | ||
const workspace = await getWorkspace(tree); | ||
const projectWorkspace = workspace.projects.get(project); | ||
|
||
if (!projectWorkspace) { | ||
throw new SchematicsException(messages.noProject(project)); | ||
} | ||
} | ||
|
||
// Installing dependencies | ||
for (const key in VERSIONS) { | ||
if (VERSIONS.hasOwnProperty(key)) { | ||
addPackageToPackageJson(tree, key, VERSIONS[key]); | ||
} | ||
} | ||
|
||
context.addTask(new RunSchematicTask('ng-add-setup-project', options), [ | ||
context.addTask(new NodePackageInstallTask()), | ||
]); | ||
}; | ||
} |
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,11 @@ | ||
export function noProject(project: string) { | ||
return `Unable to find project '${project}' in the workspace`; | ||
} | ||
|
||
export function noMainFile(projectName: string) { | ||
return `Unable to find 'build.options.main' file path for project "${projectName}"`; | ||
} | ||
|
||
export function noModuleFile(moduleFilePath: string) { | ||
return `File '${moduleFilePath}' does not exist.`; | ||
} |
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,16 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"$id": "sunbird-epub-player-ng-add", | ||
"title": "Sunbird Epub Player ng-add schematic", | ||
"type": "object", | ||
"properties": { | ||
"project": { | ||
"type": "string", | ||
"description": "Name of the project.", | ||
"$default": { | ||
"$source": "projectName" | ||
} | ||
} | ||
}, | ||
"required": [] | ||
} |
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,6 @@ | ||
export interface Schema { | ||
/** | ||
* Name of the project where sunbird-epub-player library should be installed | ||
*/ | ||
project?: string; | ||
} |
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,14 @@ | ||
import {chain, Rule} from '@angular-devkit/schematics'; | ||
import {Schema} from './schema'; | ||
import {addPlayerModuleToAppModule} from './steps/add-player-module'; | ||
import { addPlayerStyles } from './steps/add-player-style'; | ||
/** | ||
* Sets up a project with all required to run sunbird pdf player. | ||
* This is run after 'package.json' was patched and all dependencies installed | ||
*/ | ||
export default function ngAddSetupProject(options: Schema): Rule { | ||
return chain([ | ||
addPlayerModuleToAppModule(options), | ||
addPlayerStyles(options), | ||
]); | ||
} |
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,75 @@ | ||
import {Rule, SchematicsException, Tree} from '@angular-devkit/schematics'; | ||
import {getAppModulePath} from '@schematics/angular/utility/ng-ast-utils'; | ||
import {addImportToModule} from '@schematics/angular/utility/ast-utils'; | ||
import {InsertChange} from '@schematics/angular/utility/change'; | ||
import * as ts from '@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript'; | ||
import {Schema} from '../schema'; | ||
import {getWorkspace} from '@schematics/angular/utility/workspace'; | ||
import * as messages from '../messages'; | ||
import { getProjectTargetOptions } from '../../utils/project'; | ||
|
||
const MODULE_NAME = 'SunbirdEpubPlayerModule'; | ||
const PACKAGE_NAME = '@project-sunbird/sunbird-epub-player-v9'; | ||
|
||
/** | ||
* Patches main application module by adding 'SunbirdEpubPlayerModule' import. | ||
* | ||
* Relevant 'angular.json' structure is: | ||
* | ||
* { | ||
* "projects" : { | ||
* "projectName": { | ||
* "architect": { | ||
* "build": { | ||
* "options": { | ||
* "main": "src/main.ts" | ||
* } | ||
* } | ||
* } | ||
* } | ||
* }, | ||
* "defaultProject": "projectName" | ||
* } | ||
* | ||
*/ | ||
export function addPlayerModuleToAppModule(options: Schema): Rule { | ||
return async (host: Tree) => { | ||
const workspace = await getWorkspace(host); | ||
const projectName = options.project || (workspace.extensions.defaultProject as string); | ||
|
||
// 1. getting project by name | ||
const project: any = workspace.projects.get(projectName); | ||
if (!project) { | ||
throw new SchematicsException(messages.noProject(projectName)); | ||
} | ||
|
||
// 2. getting main file for project | ||
const projectBuildOptions = getProjectTargetOptions(project, 'build'); | ||
const mainFilePath = projectBuildOptions.main as string; | ||
if (!mainFilePath || !host.read(mainFilePath)) { | ||
throw new SchematicsException(messages.noMainFile(projectName)); | ||
} | ||
|
||
// 3. getting main app module file | ||
const appModuleFilePath = getAppModulePath(host, mainFilePath); | ||
const appModuleFileText = host.read(appModuleFilePath); | ||
if (appModuleFileText === null) { | ||
throw new SchematicsException(messages.noModuleFile(appModuleFilePath)); | ||
} | ||
|
||
// 4. adding `NgbModule` to the app module | ||
const appModuleSource = | ||
ts.createSourceFile(appModuleFilePath, appModuleFileText.toString('utf-8'), ts.ScriptTarget.Latest, true); | ||
|
||
const changes = | ||
addImportToModule(appModuleSource, appModuleFilePath, MODULE_NAME, PACKAGE_NAME); | ||
|
||
const recorder = host.beginUpdate(appModuleFilePath); | ||
for (const change of changes) { | ||
if (change instanceof InsertChange) { | ||
recorder.insertLeft(change.pos, change.toAdd); | ||
} | ||
} | ||
host.commitUpdate(recorder); | ||
}; | ||
} |
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,94 @@ | ||
import { Rule, Tree, SchematicsException } from '@angular-devkit/schematics'; | ||
import { Schema } from '../schema'; | ||
import * as messages from '../messages'; | ||
import { getProjectTargetOptions } from '../../utils/project'; | ||
import { getWorkspace, updateWorkspace } from '@schematics/angular/utility/workspace'; | ||
import { workspaces, JsonArray } from '@angular-devkit/core'; | ||
|
||
// Default styles, assets and script | ||
|
||
const SB_STYLES = [ | ||
'node_modules/@project-sunbird/sb-styles/assets/_styles.scss' | ||
]; | ||
const SB_ASSETS = [{ | ||
glob: '**/*.*', | ||
input: './node_modules/@project-sunbird/sunbird-epub-player-v9/lib/assets/', | ||
output: '/assets/' | ||
}]; | ||
const SB_SCRIPTS = [ | ||
'node_modules/epubjs/dist/epub.js' | ||
]; | ||
|
||
|
||
/** | ||
* we're simply adding styles to the 'angular.json' | ||
*/ | ||
export function addPlayerStyles(options: Schema): Rule { | ||
return async (host: Tree) => { | ||
const workspace: any = await getWorkspace(host); | ||
|
||
const projectName = options.project || (workspace.extensions.defaultProject as string); | ||
const project = workspace.projects.get(projectName); | ||
if (!project) { | ||
throw new SchematicsException(messages.noProject(projectName)); | ||
} | ||
// just patching 'angular.json' | ||
return addPlayerToAngularJson(workspace, project); | ||
}; | ||
} | ||
|
||
/** | ||
* Patches 'angular.json' to add styles | ||
*/ | ||
function addPlayerToAngularJson( | ||
workspace: any, | ||
project: workspaces.ProjectDefinition | ||
): Rule { | ||
const targetOptions = getProjectTargetOptions(project, 'build'); | ||
addStyleToTarget(targetOptions, SB_STYLES); | ||
addAssetsToTarget(targetOptions, SB_ASSETS); | ||
addScriptToTarget(targetOptions, SB_SCRIPTS); | ||
return updateWorkspace(workspace); | ||
} | ||
|
||
function addStyleToTarget(targetOptions: any, assetPaths: Array<any>) { | ||
const styles = (targetOptions.styles as JsonArray | undefined); | ||
if (!styles) { | ||
targetOptions.styles = assetPaths; | ||
} else { | ||
const existingStyles: any = styles.map((s: any) => typeof s === 'string' ? s : s.input); | ||
assetPaths.forEach((style: any) => { | ||
if (!existingStyles.includes(typeof style === 'string' ? style : style.input)) { | ||
styles.unshift(style); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
function addAssetsToTarget(targetOptions: any, assetPaths: Array<any>) { | ||
const assets = (targetOptions.assets as JsonArray | undefined); | ||
if (!assets) { | ||
targetOptions.assets = assetPaths; | ||
} else { | ||
const existingAssets: any = assets.map((s: any) => typeof s === 'string' ? s : s.input); | ||
assetPaths.forEach((asset: any) => { | ||
if (!existingAssets.includes(typeof asset === 'string' ? asset : asset.input)) { | ||
assets.unshift(asset); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
function addScriptToTarget(targetOptions: any, assetPaths: Array<any>) { | ||
const scripts = (targetOptions.scripts as JsonArray | undefined); | ||
if (!scripts) { | ||
targetOptions.scripts = assetPaths; | ||
} else { | ||
const existingScripts: any = scripts.map((s: any) => typeof s === 'string' ? s : s.input); | ||
assetPaths.forEach((script: any) => { | ||
if (!existingScripts.includes(typeof script === 'string' ? script : script.input)) { | ||
scripts.unshift(script); | ||
} | ||
}); | ||
} | ||
} |
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,64 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import {Tree} from '@angular-devkit/schematics'; | ||
|
||
interface PackageJson { | ||
dependencies: Record<string, string>; | ||
} | ||
|
||
/** | ||
* Sorts the keys of the given object. | ||
* @returns A new object instance with sorted keys | ||
*/ | ||
function sortObjectByKeys(obj: Record<string, string>) { | ||
return Object.keys(obj) | ||
.sort() | ||
.reduce((result, key) => { | ||
result[key] = obj[key]; | ||
return result; | ||
}, {} as Record<string, string>); | ||
} | ||
|
||
/** Adds a package to the package.json in the given host tree. */ | ||
export function addPackageToPackageJson(host: Tree, pkg: string, version: string): Tree { | ||
if (host.exists('package.json')) { | ||
// tslint:disable-next-line:no-non-null-assertion | ||
const sourceText = host.read('package.json')!.toString('utf-8'); | ||
const json = JSON.parse(sourceText) as PackageJson; | ||
|
||
if (!json.dependencies) { | ||
json.dependencies = {}; | ||
} | ||
|
||
if (!json.dependencies[pkg]) { | ||
json.dependencies[pkg] = version; | ||
json.dependencies = sortObjectByKeys(json.dependencies); | ||
} | ||
|
||
host.overwrite('package.json', JSON.stringify(json, null, 2)); | ||
} | ||
|
||
return host; | ||
} | ||
|
||
/** Gets the version of the specified package by looking at the package.json in the given tree. */ | ||
export function getPackageVersionFromPackageJson(tree: Tree, name: string): string | null { | ||
if (!tree.exists('package.json')) { | ||
return null; | ||
} | ||
|
||
// tslint:disable-next-line:no-non-null-assertion | ||
const packageJson = JSON.parse(tree.read('package.json')!.toString('utf8')) as PackageJson; | ||
|
||
if (packageJson.dependencies && packageJson.dependencies[name]) { | ||
return packageJson.dependencies[name]; | ||
} | ||
|
||
return null; | ||
} |
Oops, something went wrong.