Compare commits
7 commits
bdb2e4e02f
...
a027ba64a2
Author | SHA1 | Date | |
---|---|---|---|
a027ba64a2 | |||
ac76bf6715 | |||
6c72e6200f | |||
68378b1e86 | |||
84ada4d843 | |||
f734303a26 | |||
f1906b03cd |
23 changed files with 3496 additions and 40 deletions
|
@ -2,5 +2,8 @@
|
|||
"name": "SilverStripe Environment",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "silverstripe",
|
||||
"workspaceFolder": "/vscode/src/mantra"
|
||||
"workspaceFolder": "/vscode/src/mantra",
|
||||
"extensions": [
|
||||
"ms-vscode.vscode-typescript-tslint-plugin"
|
||||
]
|
||||
}
|
|
@ -3,7 +3,7 @@ version: '3'
|
|||
services:
|
||||
silverstripe:
|
||||
image: manuth/silverstripe-dev
|
||||
env_file: .env
|
||||
env_file: devcontainer.env
|
||||
ports:
|
||||
- 8080:80
|
||||
volumes:
|
||||
|
@ -11,6 +11,6 @@ services:
|
|||
- ../test/website:/var/www/html
|
||||
db:
|
||||
image: mysql:5
|
||||
env_file: .env
|
||||
env_file: devcontainer.env
|
||||
volumes:
|
||||
- ./mysql-data:/var/lib/mysql
|
15
.gitignore
vendored
15
.gitignore
vendored
|
@ -51,9 +51,15 @@ typings/
|
|||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Output of 'composer archive'
|
||||
*.tar
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
|
@ -77,3 +83,12 @@ vendor/
|
|||
|
||||
# MySQL cache
|
||||
.devcontainer/mysql-data
|
||||
|
||||
# Build files
|
||||
/javascript/
|
||||
/css/
|
||||
/templates/
|
||||
/assets/
|
||||
|
||||
# Test-theme
|
||||
/test/website/themes/mantra
|
||||
|
|
240
.gulp/Settings.ts
Normal file
240
.gulp/Settings.ts
Normal file
|
@ -0,0 +1,240 @@
|
|||
import Path = require("upath");
|
||||
|
||||
/**
|
||||
* Provides settings for building the project.
|
||||
*/
|
||||
export class Settings
|
||||
{
|
||||
/**
|
||||
* A value indicating whether the project should be built in watched mode.
|
||||
*/
|
||||
public Watch = false;
|
||||
|
||||
/**
|
||||
* The target of the project-build.
|
||||
*/
|
||||
public Target: string;
|
||||
|
||||
/**
|
||||
* The path to the source-code root.
|
||||
*/
|
||||
private sourceRoot = "src";
|
||||
|
||||
/**
|
||||
* The path to the root of the typescript-project.
|
||||
*/
|
||||
private typeScriptProjectRoot = "App";
|
||||
|
||||
/**
|
||||
* The path to the root of the typescript-source.
|
||||
*/
|
||||
private typeScriptSourceRoot = "src";
|
||||
|
||||
/**
|
||||
* The path to save the javascript-code to.
|
||||
*/
|
||||
private libraryPath = "javascript";
|
||||
|
||||
/**
|
||||
* The path to the root of the theme-source.
|
||||
*/
|
||||
private themeSource = "Theme";
|
||||
|
||||
/**
|
||||
* The path to save the css-code to.
|
||||
*/
|
||||
private stylePath = "css";
|
||||
|
||||
/**
|
||||
* The path to the root of the template-source.
|
||||
*/
|
||||
private templateSource = "Templates";
|
||||
|
||||
/**
|
||||
* The path to save the templates to.
|
||||
*/
|
||||
private templatePath = "templates";
|
||||
|
||||
/**
|
||||
* The path to the test-directory.
|
||||
*/
|
||||
private testPath = "test";
|
||||
|
||||
/**
|
||||
* The path to the test-website.
|
||||
*/
|
||||
private testWebsitePath = "website";
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the `Settings` class.
|
||||
*
|
||||
* @param target
|
||||
* The target of the project-build.
|
||||
*/
|
||||
public constructor(target: string)
|
||||
{
|
||||
this.Target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* A value indicating whether the debug-mode is enabled.
|
||||
*/
|
||||
public get Debug()
|
||||
{
|
||||
return this.Target === "Debug";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the root of the solution.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @return
|
||||
* The joined path.
|
||||
*/
|
||||
public RootPath(...path: string[])
|
||||
{
|
||||
return Path.join(Path.dirname(__dirname), ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the root of the source-code.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public SourceRoot(...path: string[])
|
||||
{
|
||||
return this.RootPath(this.sourceRoot, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the root of the typescript-project.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public TypeScriptProjectRoot(...path: string[])
|
||||
{
|
||||
return this.SourceRoot(this.typeScriptProjectRoot, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the root of the typescript-source.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public TypeScriptSourceRoot(...path: string[])
|
||||
{
|
||||
return this.TypeScriptProjectRoot(this.typeScriptSourceRoot, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the directory to save the javascript-code to.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public LibraryPath(...path: string[])
|
||||
{
|
||||
return this.RootPath(this.libraryPath, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the root of the theme-source.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public ThemeSource(...path: string[])
|
||||
{
|
||||
return this.SourceRoot(this.themeSource, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the directory to save the css-code to.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public StylePath(...path: string[])
|
||||
{
|
||||
return this.RootPath(this.stylePath, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the root of the template-source.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public TemplateSource(...path: string[])
|
||||
{
|
||||
return this.SourceRoot(this.templateSource, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the directory to save the templates to.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public TemplatePath(...path: string[])
|
||||
{
|
||||
return this.RootPath(this.templatePath, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the test-directory.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public TestPath(...path: string[])
|
||||
{
|
||||
return this.RootPath(this.testPath, ...path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a path relative to the test-website.
|
||||
*
|
||||
* @param path
|
||||
* The path to join.
|
||||
*
|
||||
* @returns
|
||||
* The joined path.
|
||||
*/
|
||||
public TestWebsitePath(...path: string[])
|
||||
{
|
||||
return this.TestPath(this.testWebsitePath, ...path);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,8 @@ import { TaskFunction } from "gulp";
|
|||
*/
|
||||
declare global
|
||||
{
|
||||
interface Function extends TaskFunction
|
||||
// tslint:disable-next-line: completed-docs
|
||||
interface Function extends Partial<TaskFunction>
|
||||
{ }
|
||||
}
|
||||
|
||||
|
|
15
.vscode/extensions.json
vendored
Normal file
15
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
"adrianhumphreys.silverstripe",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
"ms-vscode-remote.remote-containers"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": [
|
||||
|
||||
]
|
||||
}
|
8
.vscode/settings.json
vendored
Normal file
8
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"javascript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
|
||||
"javascript.format.placeOpenBraceOnNewLineForControlBlocks": true,
|
||||
"javascript.format.placeOpenBraceOnNewLineForFunctions": true,
|
||||
"typescript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
|
||||
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": true,
|
||||
"typescript.format.placeOpenBraceOnNewLineForFunctions": true
|
||||
}
|
|
@ -36,18 +36,26 @@
|
|||
"archive": {
|
||||
"exclude": [
|
||||
"/*.tar",
|
||||
".devcontainer",
|
||||
".gulp",
|
||||
".gitignore",
|
||||
".vscode/",
|
||||
"gulpfile.ts",
|
||||
"node_modules/",
|
||||
"package-lock.json",
|
||||
"package.json",
|
||||
"test/"
|
||||
"src/",
|
||||
"test/",
|
||||
"tsconfig.json",
|
||||
"tslint.json"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"scripts-dev": {
|
||||
"post-install-cmd": [
|
||||
"npm install"
|
||||
"npm install",
|
||||
"@initialize",
|
||||
"composer --working-dir=./test/website install"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
2
composer.lock
generated
2
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "22068a23fc6b360469aeccc3a344ead6",
|
||||
"content-hash": "848468c4f4ad00ed3629fa3cbf2bea5b",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
|
|
356
gulpfile.ts
356
gulpfile.ts
|
@ -1,11 +1,363 @@
|
|||
import browserify = require("browserify");
|
||||
import log = require("fancy-log");
|
||||
import FileSystem = require("fs-extra");
|
||||
import { TaskFunction } from "gulp";
|
||||
import gulp = require("gulp");
|
||||
import gulpIf = require("gulp-if");
|
||||
import rename = require("gulp-rename");
|
||||
import sass = require("gulp-sass");
|
||||
import terser = require("gulp-terser");
|
||||
import merge = require("merge-stream");
|
||||
import minimist = require("minimist");
|
||||
import { Server, Socket } from "net";
|
||||
import PromiseQueue = require("promise-queue");
|
||||
import { parseArgsStringToArgv } from "string-argv";
|
||||
import Path = require("upath");
|
||||
import buffer = require("vinyl-buffer");
|
||||
import vinylSourceStream = require("vinyl-source-stream");
|
||||
import Watchify = require("watchify");
|
||||
import { Settings } from "./.gulp/Settings";
|
||||
import "./.gulp/TaskFunction";
|
||||
|
||||
/**
|
||||
* The port to listen for stop-requests.
|
||||
*/
|
||||
const watchConnectorPort = 50958;
|
||||
|
||||
/**
|
||||
* The message that is printed when starting the compilation in watch mode.
|
||||
*/
|
||||
const watchStartMessage = "Starting compilation in watch mode...";
|
||||
|
||||
/**
|
||||
* The message that is printed when starting an incremental compilation.
|
||||
*/
|
||||
const incrementalMessage = "File change detected. Starting incremental compilation...";
|
||||
|
||||
/**
|
||||
* Generates the message that is printed after finishing a compilation in watch mode.
|
||||
*
|
||||
* @param errorCount
|
||||
* The number of errors which occurred.
|
||||
*/
|
||||
const watchFinishMessage = (errorCount: number) =>
|
||||
{
|
||||
return `Found ${errorCount} errors. Watching for file changes.`;
|
||||
};
|
||||
|
||||
/**
|
||||
* The arguments passed by the user.
|
||||
*/
|
||||
let options = ParseArgs(process.argv.slice(2));
|
||||
|
||||
/**
|
||||
* Parses the specified arguments.
|
||||
*
|
||||
* @param args
|
||||
* The arguments to parse.
|
||||
*/
|
||||
function ParseArgs(args: string[])
|
||||
{
|
||||
return minimist(
|
||||
args,
|
||||
{
|
||||
string: [
|
||||
"target"
|
||||
],
|
||||
alias: {
|
||||
target: "t"
|
||||
},
|
||||
default: {
|
||||
target: "Debug"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings for building the project.
|
||||
*/
|
||||
let settings = new Settings(options["target"]);
|
||||
|
||||
/**
|
||||
* Initializes the project.
|
||||
*/
|
||||
export function Initialize(done: () => void)
|
||||
export async function Initialize()
|
||||
{
|
||||
done();
|
||||
let directories = [
|
||||
"javascript",
|
||||
"css",
|
||||
"templates",
|
||||
"assets"
|
||||
];
|
||||
|
||||
let themePath = settings.TestWebsitePath("themes", Path.basename(settings.RootPath()));
|
||||
|
||||
for (let directory of directories)
|
||||
{
|
||||
await FileSystem.emptyDir(settings.RootPath(directory));
|
||||
}
|
||||
|
||||
if (await FileSystem.pathExists(themePath))
|
||||
{
|
||||
await FileSystem.remove(themePath);
|
||||
}
|
||||
|
||||
await require("create-symlink")(settings.RootPath(), themePath, { type: "junction" });
|
||||
}
|
||||
|
||||
Initialize.description = "Initializes the project.";
|
||||
|
||||
/**
|
||||
* Builds the project in watched mode.
|
||||
*/
|
||||
export let Watch: TaskFunction = (done) =>
|
||||
{
|
||||
settings.Watch = true;
|
||||
Build();
|
||||
|
||||
let server = new Server(
|
||||
(socket) =>
|
||||
{
|
||||
socket.on(
|
||||
"data",
|
||||
(data) =>
|
||||
{
|
||||
let args = parseArgsStringToArgv(data.toString());
|
||||
socket.destroy();
|
||||
|
||||
if (args[0] === "stop")
|
||||
{
|
||||
let options = ParseArgs(args.slice(1));
|
||||
|
||||
if (options["target"] === settings.Target)
|
||||
{
|
||||
server.close();
|
||||
done();
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(watchConnectorPort);
|
||||
};
|
||||
|
||||
Watch.description = "Builds the project in watched mode.";
|
||||
|
||||
/**
|
||||
* Builds the project.
|
||||
*/
|
||||
export async function Build()
|
||||
{
|
||||
if (settings.Watch)
|
||||
{
|
||||
log.info(watchStartMessage);
|
||||
gulp.watch(settings.ThemeSource("**"), Theme);
|
||||
gulp.watch(settings.TemplateSource("**"), Templates);
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
[
|
||||
Library(),
|
||||
Theme(),
|
||||
Templates()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the TypeScript- and JavaScript-library.
|
||||
*/
|
||||
export async function Library()
|
||||
{
|
||||
let streams: Array<Promise<NodeJS.ReadWriteStream>> = [];
|
||||
let queue = new PromiseQueue();
|
||||
let tsConfigFile = settings.TypeScriptProjectRoot("tsconfig.json");
|
||||
let tsConfig = require(tsConfigFile);
|
||||
|
||||
let optionBase: browserify.Options = {
|
||||
...Watchify.args,
|
||||
node: true,
|
||||
ignoreMissing: true,
|
||||
debug: settings.Debug
|
||||
};
|
||||
|
||||
{
|
||||
let errorMessages: string[] = [];
|
||||
let files = (tsConfig.files as string[]).map(
|
||||
(file) => Path.relative(settings.TypeScriptSourceRoot(), settings.TypeScriptProjectRoot(file)));
|
||||
|
||||
for (let file of files)
|
||||
{
|
||||
let bundler = browserify(
|
||||
{
|
||||
...optionBase,
|
||||
basedir: settings.LibraryPath(Path.dirname(file)),
|
||||
entries: [
|
||||
settings.TypeScriptSourceRoot(file)
|
||||
],
|
||||
standalone: Path.join(Path.dirname(file), Path.parse(file).name)
|
||||
});
|
||||
|
||||
if (settings.Watch)
|
||||
{
|
||||
bundler = Watchify(bundler);
|
||||
}
|
||||
|
||||
bundler.plugin(
|
||||
require("tsify"),
|
||||
{
|
||||
project: tsConfigFile
|
||||
});
|
||||
|
||||
let bundle = async () =>
|
||||
{
|
||||
return new Promise<NodeJS.ReadWriteStream>(
|
||||
(resolve) =>
|
||||
{
|
||||
let stream = bundler.bundle().on(
|
||||
"error",
|
||||
(error) =>
|
||||
{
|
||||
let message: string = error.message;
|
||||
|
||||
if (!errorMessages.includes(message))
|
||||
{
|
||||
errorMessages.push(message);
|
||||
log.error(message);
|
||||
}
|
||||
}
|
||||
).pipe(
|
||||
vinylSourceStream(Path.changeExt(file, "js"))
|
||||
).pipe(
|
||||
buffer()
|
||||
).pipe(
|
||||
gulpIf(
|
||||
!settings.Debug,
|
||||
terser()
|
||||
)
|
||||
).pipe(
|
||||
gulp.dest(settings.LibraryPath())
|
||||
);
|
||||
|
||||
stream.on(
|
||||
"end",
|
||||
() =>
|
||||
{
|
||||
if (settings.Watch && ((queue.getQueueLength() + queue.getPendingLength()) === 1))
|
||||
{
|
||||
log.info(watchFinishMessage(errorMessages.length));
|
||||
}
|
||||
|
||||
errorMessages.splice(0, errorMessages.length);
|
||||
resolve(stream);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (settings.Watch)
|
||||
{
|
||||
bundler.on(
|
||||
"update",
|
||||
() =>
|
||||
{
|
||||
if ((queue.getQueueLength() + queue.getPendingLength()) === 0)
|
||||
{
|
||||
log.info(incrementalMessage);
|
||||
}
|
||||
|
||||
queue.add(
|
||||
async () =>
|
||||
{
|
||||
return bundle();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let build = () => queue.add(bundle);
|
||||
build.displayName = Build.displayName;
|
||||
build.description = Build.description;
|
||||
streams.push(build());
|
||||
}
|
||||
}
|
||||
|
||||
return merge(await Promise.all(streams)) as NodeJS.ReadWriteStream;
|
||||
}
|
||||
|
||||
Library.description = "Builds the TypeScript- and JavaScript-library.";
|
||||
|
||||
/**
|
||||
* Builds the theme.
|
||||
*/
|
||||
export async function Theme()
|
||||
{
|
||||
return gulp.src(
|
||||
settings.ThemeSource("main.scss"),
|
||||
{
|
||||
sourcemaps: settings.Debug,
|
||||
base: settings.StylePath()
|
||||
}).pipe(
|
||||
sass({ importer: require("node-sass-tilde-importer") })
|
||||
).pipe(
|
||||
rename(
|
||||
(parsedPath) =>
|
||||
{
|
||||
parsedPath.dirname = "";
|
||||
parsedPath.basename = "mantra";
|
||||
})
|
||||
).pipe(
|
||||
gulp.dest(
|
||||
settings.StylePath(),
|
||||
settings.Debug ?
|
||||
{
|
||||
sourcemaps: true
|
||||
}
|
||||
:
|
||||
undefined)
|
||||
);
|
||||
}
|
||||
|
||||
Theme.description = "Builds the theme.";
|
||||
|
||||
/**
|
||||
* Builds the templates.
|
||||
*/
|
||||
export function Templates()
|
||||
{
|
||||
return gulp.src(
|
||||
settings.TemplateSource("**")).pipe(
|
||||
gulp.dest(settings.TemplatePath()));
|
||||
}
|
||||
|
||||
Templates.description = "Builds the templates.";
|
||||
|
||||
/**
|
||||
* Stops a watch-task.
|
||||
*/
|
||||
export async function Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
await new Promise(
|
||||
(resolve, reject) =>
|
||||
{
|
||||
let client = new Socket();
|
||||
|
||||
client.connect(
|
||||
watchConnectorPort,
|
||||
"localhost",
|
||||
async () =>
|
||||
{
|
||||
client.write(`stop -t ${settings.Target}`);
|
||||
});
|
||||
|
||||
client.on("close", resolve);
|
||||
client.on("error", reject);
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
log.info("The specified task is not running.");
|
||||
}
|
||||
}
|
||||
|
||||
Stop.description = "Stops a watch-task";
|
2688
package-lock.json
generated
2688
package-lock.json
generated
File diff suppressed because it is too large
Load diff
43
package.json
43
package.json
|
@ -5,9 +5,50 @@
|
|||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@manuth/tsconfig": "^1.2.2",
|
||||
"@manuth/tslint-presets": "^1.0.4",
|
||||
"@types/bootstrap": "^4.3.1",
|
||||
"@types/browserify": "^12.0.36",
|
||||
"@types/fancy-log": "^1.3.1",
|
||||
"@types/fs-extra": "^8.0.0",
|
||||
"@types/gulp": "^4.0.6",
|
||||
"@types/gulp-if": "0.0.33",
|
||||
"@types/gulp-rename": "0.0.33",
|
||||
"@types/gulp-sass": "^4.0.0",
|
||||
"@types/gulp-terser": "^1.2.0",
|
||||
"@types/jquery": "^3.3.31",
|
||||
"@types/merge-stream": "^1.1.2",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/node": "^12.7.11",
|
||||
"@types/promise-queue": "^2.2.0",
|
||||
"@types/vinyl-buffer": "^1.0.0",
|
||||
"@types/vinyl-source-stream": "0.0.30",
|
||||
"@types/watchify": "^3.7.4",
|
||||
"bootstrap": "^4.3.1",
|
||||
"browserify": "^16.5.0",
|
||||
"create-symlink": "^1.0.0",
|
||||
"fancy-log": "^1.3.3",
|
||||
"fs-extra": "^8.1.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-if": "^3.0.0",
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-sass": "^4.0.2",
|
||||
"gulp-terser": "^1.2.0",
|
||||
"jquery": "^3.4.1",
|
||||
"merge-stream": "^2.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
"node-sass-tilde-importer": "^1.0.2",
|
||||
"popper.js": "^1.15.0",
|
||||
"promise-queue": "^2.2.5",
|
||||
"string-argv": "^0.3.1",
|
||||
"ts-node": "^8.4.1",
|
||||
"typescript": "^3.6.3"
|
||||
"tsify": "^4.0.1",
|
||||
"tslint": "^5.20.0",
|
||||
"typescript": "^3.6.3",
|
||||
"typescript-tslint-plugin": "^0.5.4",
|
||||
"upath": "^1.2.0",
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
"vinyl-source-stream": "^2.0.0",
|
||||
"watchify": "^3.11.1"
|
||||
}
|
||||
}
|
||||
|
|
3
src/App/src/main.ts
Normal file
3
src/App/src/main.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import "bootstrap";
|
||||
import "jquery";
|
||||
import "popper.js";
|
13
src/App/tsconfig.json
Normal file
13
src/App/tsconfig.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"files": [
|
||||
"src/main.ts"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"lib": [
|
||||
"es7",
|
||||
"dom"
|
||||
],
|
||||
"target": "es5"
|
||||
}
|
||||
}
|
0
src/Templates/Layout/Page.ss
Normal file
0
src/Templates/Layout/Page.ss
Normal file
45
src/Templates/Page.ss
Normal file
45
src/Templates/Page.ss
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
<!doctype html>
|
||||
<html class="h-100">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<% base_tag %>
|
||||
$MetaTags()
|
||||
<% require themedCSS("mantra") %>
|
||||
<% require themedJavascript("mantra") %>
|
||||
</head>
|
||||
<body class="d-flex flex-column h-100">
|
||||
<% if $Menu(1) %>
|
||||
<div class="col-1">
|
||||
<nav>
|
||||
<div class="active">
|
||||
<a>
|
||||
$Title
|
||||
</a>
|
||||
<ul class="nav bd-sidenav">
|
||||
<% loop $Menu(1) %>
|
||||
<li class="$LinkingMode">
|
||||
<a href="$Link">
|
||||
$MenuTitle
|
||||
</a>
|
||||
</li>
|
||||
<% end_loop %>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<% end_if %>
|
||||
<main role="main" class="col-11 flex-shrink-0">
|
||||
<div class="container">
|
||||
<% loop $Menu(1) %>
|
||||
<li><a class="$LinkingMode" href="$Link" title="Go to the $Title page">$MenuTitle</a></li>
|
||||
<% end_loop %>
|
||||
<h1 class="display-4">
|
||||
$MenuTitle
|
||||
</h1>
|
||||
$Content
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
1
src/Theme/main.scss
Normal file
1
src/Theme/main.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "~bootstrap/scss/bootstrap";
|
|
@ -3,6 +3,6 @@ Name: mytheme
|
|||
---
|
||||
SilverStripe\View\SSViewer:
|
||||
themes:
|
||||
- 'mantra'
|
||||
- '$public'
|
||||
- 'simple'
|
||||
- '$default'
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
"phpunit/phpunit": "^5.7"
|
||||
},
|
||||
"extra": {
|
||||
"expose": [
|
||||
"themes/mantra/assets",
|
||||
"themes/mantra/css",
|
||||
"themes/mantra/javascript"
|
||||
],
|
||||
"resources-dir": "_resources",
|
||||
"project-files-installed": [
|
||||
"app/.htaccess",
|
||||
|
|
44
test/website/composer.lock
generated
44
test/website/composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "7ff31cbd9aa5ee75c9624d2bb8c3bc5f",
|
||||
"content-hash": "0ab3e4aaf71526993c3dbb3ea6179605",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bramus/ansi-php",
|
||||
|
@ -2216,16 +2216,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v3.4.31",
|
||||
"version": "v3.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache.git",
|
||||
"reference": "6a9cc3ed7f61c6c2bc042d0594cdb807b6fea62c"
|
||||
"reference": "5c7bd827617fcb9b13e04e423c31c0fb0bcf0160"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/6a9cc3ed7f61c6c2bc042d0594cdb807b6fea62c",
|
||||
"reference": "6a9cc3ed7f61c6c2bc042d0594cdb807b6fea62c",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/5c7bd827617fcb9b13e04e423c31c0fb0bcf0160",
|
||||
"reference": "5c7bd827617fcb9b13e04e423c31c0fb0bcf0160",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2282,20 +2282,20 @@
|
|||
"caching",
|
||||
"psr6"
|
||||
],
|
||||
"time": "2019-08-26T07:52:58+00:00"
|
||||
"time": "2019-09-29T21:19:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v3.4.31",
|
||||
"version": "v3.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/config.git",
|
||||
"reference": "24a60c0d7ad98a0fa5d1f892e9286095a389404f"
|
||||
"reference": "717ad66b5257e9752ae3c5722b5810bb4c40b236"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/24a60c0d7ad98a0fa5d1f892e9286095a389404f",
|
||||
"reference": "24a60c0d7ad98a0fa5d1f892e9286095a389404f",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/717ad66b5257e9752ae3c5722b5810bb4c40b236",
|
||||
"reference": "717ad66b5257e9752ae3c5722b5810bb4c40b236",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2346,11 +2346,11 @@
|
|||
],
|
||||
"description": "Symfony Config Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2019-08-26T07:52:57+00:00"
|
||||
"time": "2019-09-19T15:32:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v4.3.4",
|
||||
"version": "v4.3.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
|
@ -2400,16 +2400,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v3.4.31",
|
||||
"version": "v3.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "1fcad80b440abcd1451767349906b6f9d3961d37"
|
||||
"reference": "2b6a666d6ff7fb65d10b97d817c8e7930944afb9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/1fcad80b440abcd1451767349906b6f9d3961d37",
|
||||
"reference": "1fcad80b440abcd1451767349906b6f9d3961d37",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/2b6a666d6ff7fb65d10b97d817c8e7930944afb9",
|
||||
"reference": "2b6a666d6ff7fb65d10b97d817c8e7930944afb9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2445,7 +2445,7 @@
|
|||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2019-08-14T09:39:58+00:00"
|
||||
"time": "2019-09-01T21:32:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-apcu",
|
||||
|
@ -2686,16 +2686,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v3.4.31",
|
||||
"version": "v3.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "3dc414b7db30695bae671a1d86013d03f4ae9834"
|
||||
"reference": "768f817446da74a776a31eea335540f9dcb53942"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/3dc414b7db30695bae671a1d86013d03f4ae9834",
|
||||
"reference": "3dc414b7db30695bae671a1d86013d03f4ae9834",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/768f817446da74a776a31eea335540f9dcb53942",
|
||||
"reference": "768f817446da74a776a31eea335540f9dcb53942",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2741,7 +2741,7 @@
|
|||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2019-08-20T13:31:17+00:00"
|
||||
"time": "2019-09-10T10:38:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webonyx/graphql-php",
|
||||
|
|
18
tsconfig.json
Normal file
18
tsconfig.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "@manuth/tsconfig/recommended",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es7"
|
||||
],
|
||||
"plugins": [
|
||||
{
|
||||
"name": "typescript-tslint-plugin"
|
||||
}
|
||||
],
|
||||
"target": "es5"
|
||||
},
|
||||
"files": [
|
||||
"./gulpfile.ts"
|
||||
]
|
||||
}
|
6
tslint.json
Normal file
6
tslint.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"extends": "@manuth/tslint-presets/recommended",
|
||||
"rules": {
|
||||
"interface-name": false
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue