updates
This commit is contained in:
parent
f3b37cc75a
commit
91927d3b50
6
.gitignore
vendored
6
.gitignore
vendored
@ -10,8 +10,12 @@ build/
|
|||||||
out/
|
out/
|
||||||
|
|
||||||
secret.gradle
|
secret.gradle
|
||||||
local.properties
|
local.*
|
||||||
|
local/
|
||||||
|
kotlin-js-store
|
||||||
|
|
||||||
publishing.sh
|
publishing.sh
|
||||||
|
|
||||||
server/src/resources/web/
|
server/src/resources/web/
|
||||||
|
|
||||||
|
features/common/common/src/commonMain/kotlin/dev/inmo/postssystem/features/common/common/Version.kt
|
||||||
|
@ -27,9 +27,9 @@ kotlin {
|
|||||||
|
|
||||||
api project(":postssystem.services.posts.client")
|
api project(":postssystem.services.posts.client")
|
||||||
|
|
||||||
api "dev.inmo:micro_utils.fsm.common:$microutils_version"
|
api libs.microutils.fsm.common
|
||||||
api "dev.inmo:micro_utils.fsm.repos.common:$microutils_version"
|
api libs.microutils.fsm.repos.common
|
||||||
api "dev.inmo:micro_utils.crypto:$microutils_version"
|
api libs.microutils.crypto
|
||||||
|
|
||||||
implementation compose.runtime
|
implementation compose.runtime
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class AuthView(
|
|||||||
UIKitFlex.Alignment.Horizontal.Center
|
UIKitFlex.Alignment.Horizontal.Center
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
Attrs(UIKitText.Alignment.Center),
|
Attrs(UIKitText.Alignment.Horizontal.Center),
|
||||||
bodyAttrs = Attrs(UIKitWidth.Fixed.Medium),
|
bodyAttrs = Attrs(UIKitWidth.Fixed.Medium),
|
||||||
) {
|
) {
|
||||||
CardTitle { Text("Log in") }
|
CardTitle { Text("Log in") }
|
||||||
|
8
client/uikit/.gitignore
vendored
8
client/uikit/.gitignore
vendored
@ -1,8 +1,8 @@
|
|||||||
|
artifacts
|
||||||
|
!build
|
||||||
dist/
|
dist/
|
||||||
node_modules
|
node_modules
|
||||||
tests/
|
tests
|
||||||
custom
|
|
||||||
themes.json
|
themes.json
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/.idea
|
.idea
|
||||||
/.vscode
|
|
||||||
|
24
client/uikit/build/.eslintrc.json
Normal file
24
client/uikit/build/.eslintrc.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"es2021": true,
|
||||||
|
"node": true,
|
||||||
|
"browser": false,
|
||||||
|
"commonjs": false
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"../.eslintrc.json"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2022
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["wrapper/*.js"],
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"node": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
91
client/uikit/build/build.js
Normal file
91
client/uikit/build/build.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import camelize from 'camelcase';
|
||||||
|
import {basename, resolve} from 'path';
|
||||||
|
import {args, compile, glob, icons} from './util.js';
|
||||||
|
|
||||||
|
const bundles = getBundleTasks();
|
||||||
|
const components = await getComponentTasks();
|
||||||
|
const buildAll = args.all || !Object.keys(args).filter(name =>
|
||||||
|
!['d', 'debug', 'nominify', 'watch', '_'].includes(name)
|
||||||
|
).length;
|
||||||
|
|
||||||
|
if (args.h || args.help) {
|
||||||
|
console.log(`
|
||||||
|
usage:
|
||||||
|
|
||||||
|
build.js [componentA, componentB, ...] [-d|debug|nominify|watch]
|
||||||
|
|
||||||
|
examples:
|
||||||
|
|
||||||
|
build.js // builds all of uikit, including icons, components and does minification (implies 'all')
|
||||||
|
build.js uikit icons -d // builds uikit and the icons, skipping the minification and components
|
||||||
|
build.js core lightbox -d // builds uikit-core and the lightbox, skipping the minification
|
||||||
|
|
||||||
|
available components:
|
||||||
|
|
||||||
|
bundles: ${Object.keys(bundles).join(', ')}
|
||||||
|
components: ${Object.keys(components).join(', ')}
|
||||||
|
|
||||||
|
`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let tasks;
|
||||||
|
const allTasks = {...bundles, ...components};
|
||||||
|
if (buildAll) {
|
||||||
|
tasks = allTasks;
|
||||||
|
} else if (args.components) {
|
||||||
|
tasks = components;
|
||||||
|
} else {
|
||||||
|
tasks = Object.keys(args)
|
||||||
|
.map(step => allTasks[step])
|
||||||
|
.filter(t => t);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(Object.values(tasks).map(task => task()));
|
||||||
|
|
||||||
|
function getBundleTasks() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
core: () => compile('src/js/uikit-core.js', 'dist/js/uikit-core'),
|
||||||
|
|
||||||
|
uikit: () => compile('src/js/uikit.js', 'dist/js/uikit'),
|
||||||
|
|
||||||
|
icons: async () => compile('build/wrapper/icons.js', 'dist/js/uikit-icons', {
|
||||||
|
name: 'icons',
|
||||||
|
replaces: {ICONS: await icons('{src/images,custom}/icons/*.svg')}
|
||||||
|
}),
|
||||||
|
|
||||||
|
tests: async () => compile('tests/js/index.js', 'tests/js/test', {
|
||||||
|
name: 'test',
|
||||||
|
replaces: {TESTS: await getTestFiles()}
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getComponentTasks() {
|
||||||
|
|
||||||
|
const components = await glob('src/js/components/!(index).js');
|
||||||
|
|
||||||
|
return components.reduce((components, file) => {
|
||||||
|
|
||||||
|
const name = basename(file, '.js');
|
||||||
|
|
||||||
|
components[name] = () =>
|
||||||
|
compile('build/wrapper/component.js', `dist/js/components/${name}`, {
|
||||||
|
name,
|
||||||
|
external: ['uikit', 'uikit-util'],
|
||||||
|
globals: {uikit: 'UIkit', 'uikit-util': 'UIkit.util'},
|
||||||
|
aliases: {component: resolve('src/js/components', name)},
|
||||||
|
replaces: {NAME: `'${camelize(name)}'`}
|
||||||
|
});
|
||||||
|
|
||||||
|
return components;
|
||||||
|
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getTestFiles() {
|
||||||
|
const files = await glob('tests/!(index).html', {nosort: true});
|
||||||
|
return JSON.stringify(files.map(file => basename(file, '.html')));
|
||||||
|
}
|
38
client/uikit/build/icons.js
Normal file
38
client/uikit/build/icons.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import {args, compile, glob, icons} from './util.js';
|
||||||
|
|
||||||
|
if (args.h || args.help) {
|
||||||
|
console.log(`
|
||||||
|
|
||||||
|
Builds additional custom uikit icons found in './custom/*/icons'
|
||||||
|
|
||||||
|
usage:
|
||||||
|
|
||||||
|
icons.js [custom|name]
|
||||||
|
|
||||||
|
-c|--custom
|
||||||
|
Specify custom folder to look for icons (default: './custom/*/icons')
|
||||||
|
-n|--name
|
||||||
|
Specify name regex to match against folder (default: '([a-z]+)/icons$')
|
||||||
|
|
||||||
|
`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = args.c || args.custom || 'custom/*/icons';
|
||||||
|
const match = args.n || args.name || '([a-z]+)/icons$';
|
||||||
|
|
||||||
|
await Promise.all((await glob(path)).map(compileIcons));
|
||||||
|
|
||||||
|
async function compileIcons(folder) {
|
||||||
|
const [, name] = folder.toString().match(new RegExp(match, 'i'));
|
||||||
|
return compile(
|
||||||
|
'build/wrapper/icons.js',
|
||||||
|
`dist/js/uikit-icons-${name}`,
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
replaces: {
|
||||||
|
ICONS: await icons(`{src/images/icons,${folder}}/*.svg`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
91
client/uikit/build/less.js
Normal file
91
client/uikit/build/less.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import rtlcss from 'rtlcss';
|
||||||
|
import {basename} from 'path';
|
||||||
|
import {args, banner, glob, minify, pathExists, read, readJson, renderLess, write} from './util.js';
|
||||||
|
|
||||||
|
const {rtl} = args;
|
||||||
|
const develop = args.develop || args.debug || args.d || args.nominify;
|
||||||
|
const sources = [
|
||||||
|
{src: 'src/less/uikit.less', dist: `dist/css/uikit-core${rtl ? '-rtl' : ''}.css`},
|
||||||
|
{src: 'src/less/uikit.theme.less', dist: `dist/css/uikit${rtl ? '-rtl' : ''}.css`}
|
||||||
|
];
|
||||||
|
|
||||||
|
const themes = await pathExists('themes.json') ? await readJson('themes.json') : {};
|
||||||
|
|
||||||
|
for (const src of await glob('custom/*.less')) {
|
||||||
|
const theme = basename(src, '.less');
|
||||||
|
const dist = `dist/css/uikit.${theme}${rtl ? '-rtl' : ''}.css`;
|
||||||
|
|
||||||
|
themes[theme] = {css: `../${dist}`};
|
||||||
|
|
||||||
|
if (await pathExists(`dist/js/uikit-icons-${theme}.js`)) {
|
||||||
|
themes[theme].icons = `../dist/js/uikit-icons-${theme}.js`;
|
||||||
|
}
|
||||||
|
|
||||||
|
sources.push({src, dist});
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(sources.map(({src, dist}) => compile(src, dist, develop, rtl)));
|
||||||
|
|
||||||
|
if (!rtl && (Object.keys(themes).length || !await pathExists('themes.json'))) {
|
||||||
|
await write('themes.json', JSON.stringify(themes));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function compile(file, dist, develop, rtl) {
|
||||||
|
|
||||||
|
const less = await read(file);
|
||||||
|
|
||||||
|
let output = (await renderLess(less, {
|
||||||
|
relativeUrls: true,
|
||||||
|
rootpath: '../../',
|
||||||
|
paths: ['src/less/', 'custom/']
|
||||||
|
})).replace(/\.\.\/dist\//g, '');
|
||||||
|
|
||||||
|
if (rtl) {
|
||||||
|
output = rtlcss.process(
|
||||||
|
output,
|
||||||
|
{
|
||||||
|
stringMap: [{
|
||||||
|
name: 'previous-next',
|
||||||
|
priority: 100,
|
||||||
|
search: ['previous', 'Previous', 'PREVIOUS'],
|
||||||
|
replace: ['next', 'Next', 'NEXT'],
|
||||||
|
options: {
|
||||||
|
scope: '*',
|
||||||
|
ignoreCase: false
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: 'customNegate',
|
||||||
|
priority: 50,
|
||||||
|
directives: {
|
||||||
|
control: {},
|
||||||
|
value: []
|
||||||
|
},
|
||||||
|
processors: [
|
||||||
|
{
|
||||||
|
expr: ['--uk-position-translate-x', 'stroke-dashoffset'].join('|'),
|
||||||
|
action(prop, value, context) {
|
||||||
|
return {prop, value: context.util.negate(value)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
pre(root, postcss) {
|
||||||
|
root.prepend(postcss.comment({text: 'rtl:begin:rename'}));
|
||||||
|
root.append(postcss.comment({text: 'rtl:end:rename'}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await write(dist, banner + output);
|
||||||
|
|
||||||
|
if (!develop) {
|
||||||
|
await minify(dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
4
client/uikit/build/package.json
Normal file
4
client/uikit/build/package.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"type": "module"
|
||||||
|
}
|
70
client/uikit/build/prefix.js
Normal file
70
client/uikit/build/prefix.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import inquirer from 'inquirer';
|
||||||
|
import {args, glob, read, replaceInFile, validClassName} from './util.js';
|
||||||
|
|
||||||
|
if (args.h || args.help) {
|
||||||
|
console.log(`
|
||||||
|
usage:
|
||||||
|
|
||||||
|
prefix.js [-p{refix}=your_great_new_prefix]
|
||||||
|
|
||||||
|
example:
|
||||||
|
|
||||||
|
prefix.js // will prompt for a prefix to replace the current one with
|
||||||
|
prefix.js -p=xyz // will replace any existing prefix with xyz
|
||||||
|
|
||||||
|
`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentPrefix = await findExistingPrefix();
|
||||||
|
const prefix = await getPrefix();
|
||||||
|
|
||||||
|
if (currentPrefix === prefix) {
|
||||||
|
throw new Error(`already prefixed with: ${prefix}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await replacePrefix(currentPrefix, prefix);
|
||||||
|
|
||||||
|
async function findExistingPrefix() {
|
||||||
|
const data = await read('dist/css/uikit.css');
|
||||||
|
const res = data.match(new RegExp(`(${validClassName.source})(-[a-z]+)?-grid`));
|
||||||
|
return res && res[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getPrefix() {
|
||||||
|
|
||||||
|
const prefixFromInput = args.p || args.prefix;
|
||||||
|
|
||||||
|
if (!prefixFromInput) {
|
||||||
|
|
||||||
|
const prompt = inquirer.createPromptModule();
|
||||||
|
|
||||||
|
return (await prompt({
|
||||||
|
name: 'prefix',
|
||||||
|
message: 'enter a prefix',
|
||||||
|
validate: (val, res) => val.length && val.match(validClassName) ? !!(res.prefix = val) : 'invalid prefix'
|
||||||
|
})).prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validClassName.test(prefixFromInput)) {
|
||||||
|
return prefixFromInput;
|
||||||
|
} else {
|
||||||
|
throw `illegal prefix: ${prefixFromInput}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function replacePrefix(from, to) {
|
||||||
|
for (const file of await glob('dist/**/*.css')) {
|
||||||
|
await replaceInFile(file, data => data.replace(
|
||||||
|
new RegExp(`${from}-${/([a-z\d-]+)/.source}`, 'g'),
|
||||||
|
`${to}-$1`
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of await glob('dist/**/*.js')) {
|
||||||
|
await replaceInFile(file, data => data
|
||||||
|
.replace(new RegExp(`${from}-`, 'g'), `${to}-`)
|
||||||
|
.replace(new RegExp(`(${from})?UIkit`, 'g'), `${to === 'uk' ? '' : to}UIkit`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
36
client/uikit/build/publishDev.js
Executable file
36
client/uikit/build/publishDev.js
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
import semver from 'semver';
|
||||||
|
import {args, getVersion, run} from './util.js';
|
||||||
|
|
||||||
|
const {inc} = semver;
|
||||||
|
|
||||||
|
// default exec options
|
||||||
|
if (args.f || args.force || await isDevCommit()) {
|
||||||
|
|
||||||
|
// increase version patch number
|
||||||
|
const version = inc(await getVersion(), 'patch');
|
||||||
|
|
||||||
|
// get current git hash
|
||||||
|
const hash = (await run('git rev-parse --short HEAD')).trim();
|
||||||
|
|
||||||
|
// set version of package.json
|
||||||
|
await run(`npm version ${version}-dev.${hash} --git-tag-version false`);
|
||||||
|
|
||||||
|
// create dist files
|
||||||
|
await run('yarn compile && yarn compile-rtl && yarn build-scss');
|
||||||
|
|
||||||
|
// publish to dev tag
|
||||||
|
await run('npm publish --tag dev');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isDevCommit() {
|
||||||
|
|
||||||
|
// check for changes to publish (%B: raw body (unwrapped subject and body)
|
||||||
|
const message = await run('git log -1 --pretty=%B');
|
||||||
|
|
||||||
|
// https://www.conventionalcommits.org/en/v1.0.0/
|
||||||
|
const type = message.match(/^(revert: )?(feat|fix|polish|docs|style|refactor|perf|test|workflow|ci|chore|types|build)(\(.+\))?: .{1,50}/);
|
||||||
|
|
||||||
|
return type && ['feat', 'fix', 'refactor', 'perf'].includes(type[2]);
|
||||||
|
|
||||||
|
}
|
62
client/uikit/build/release.js
Normal file
62
client/uikit/build/release.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import archiver from 'archiver';
|
||||||
|
import inquirer from 'inquirer';
|
||||||
|
import dateFormat from 'dateformat/lib/dateformat.js';
|
||||||
|
import {createWriteStream} from 'fs';
|
||||||
|
import semver from 'semver';
|
||||||
|
import {args, getVersion, glob, logFile, replaceInFile, run} from './util.js';
|
||||||
|
|
||||||
|
const {coerce, inc, prerelease, valid} = semver;
|
||||||
|
|
||||||
|
const prevVersion = await getVersion();
|
||||||
|
const version = await inquireVersion(args.v || args.version);
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
run(`npm version ${version} --git-tag-version false`),
|
||||||
|
replaceInFile('CHANGELOG.md', data =>
|
||||||
|
data.replace(/^##\s*WIP/m, `## ${versionFormat(version)} (${dateFormat(Date.now(), 'mmmm d, yyyy')})`)
|
||||||
|
),
|
||||||
|
replaceInFile('.github/ISSUE_TEMPLATE/bug-report.md', data =>
|
||||||
|
data.replace(prevVersion, version)
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
|
||||||
|
await run('yarn compile');
|
||||||
|
await run('yarn compile-rtl');
|
||||||
|
await run('yarn build-scss');
|
||||||
|
|
||||||
|
await createPackage(version);
|
||||||
|
|
||||||
|
async function inquireVersion(v) {
|
||||||
|
|
||||||
|
if (valid(v)) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
const prompt = inquirer.createPromptModule();
|
||||||
|
|
||||||
|
return (await prompt({
|
||||||
|
name: 'version',
|
||||||
|
message: 'Enter a version',
|
||||||
|
default: () => inc(prevVersion, prerelease(prevVersion) ? 'prerelease' : 'patch'),
|
||||||
|
validate: val => !!val.length || 'Invalid version'
|
||||||
|
})).version;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createPackage(version) {
|
||||||
|
const file = `dist/uikit-${version}.zip`;
|
||||||
|
const archive = archiver('zip');
|
||||||
|
|
||||||
|
archive.pipe(createWriteStream(file));
|
||||||
|
|
||||||
|
(await glob('dist/{js,css}/uikit?(-icons|-rtl)?(.min).{js,css}')).forEach(file =>
|
||||||
|
archive.file(file, {name: file.substring(5)})
|
||||||
|
);
|
||||||
|
|
||||||
|
await archive.finalize();
|
||||||
|
await logFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
function versionFormat(version) {
|
||||||
|
return [coerce(version).version].concat(prerelease(version) || []).join(' ');
|
||||||
|
}
|
91
client/uikit/build/scope.js
Normal file
91
client/uikit/build/scope.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import {args, glob, minify, read, renderLess, replaceInFile, validClassName} from './util.js';
|
||||||
|
|
||||||
|
if (args.h || args.help) {
|
||||||
|
console.log(`
|
||||||
|
usage:
|
||||||
|
|
||||||
|
scope.js [-s{cope}=your_great_new_scope_name][cleanup]
|
||||||
|
|
||||||
|
example:
|
||||||
|
|
||||||
|
scope.js // will scope with uk-scope
|
||||||
|
scope.js -s "my-scope" // will replace any existing scope with my-scope
|
||||||
|
scope.js cleanup // will remove current scope
|
||||||
|
|
||||||
|
`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
const currentScopeRe = /\/\* scoped: ([^*]*) \*\/\n/;
|
||||||
|
const currentScopeLegacyRe = /\.(uk-scope)/;
|
||||||
|
|
||||||
|
const files = await glob('dist/**/!(*.min).css');
|
||||||
|
const prevScope = await getScope(files);
|
||||||
|
|
||||||
|
if (args.cleanup && prevScope) {
|
||||||
|
await cleanup(files, prevScope);
|
||||||
|
} else if (prevScope) {
|
||||||
|
const newScope = getNewScope();
|
||||||
|
|
||||||
|
if (prevScope === newScope) {
|
||||||
|
console.warn(`Already scoped with: ${prevScope}`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await cleanup(files, prevScope);
|
||||||
|
await scope(files, newScope);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
await scope(files, getNewScope());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getScope(files) {
|
||||||
|
for (const file of files) {
|
||||||
|
const data = await read(file);
|
||||||
|
const [, scope] = (data.match(currentScopeRe) || data.match(currentScopeLegacyRe) || []);
|
||||||
|
if (scope) {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNewScope() {
|
||||||
|
|
||||||
|
const scopeFromInput = args.scope || args.s || 'uk-scope';
|
||||||
|
|
||||||
|
if (validClassName.test(scopeFromInput)) {
|
||||||
|
return scopeFromInput;
|
||||||
|
} else {
|
||||||
|
throw `Illegal scope-name: ${scopeFromInput}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function scope(files, scope) {
|
||||||
|
for (const file of files) {
|
||||||
|
await replaceInFile(file, async data => {
|
||||||
|
const output = await renderLess(`.${scope} {\n${stripComments(data)}\n}`);
|
||||||
|
return `/* scoped: ${scope} */\n${
|
||||||
|
output.replace(new RegExp(`.${scope}\\s((\\.(uk-(drag|modal-page|offcanvas-page|offcanvas-flip)))|html|:root)`, 'g'), '$1') // unescape
|
||||||
|
}`;
|
||||||
|
});
|
||||||
|
await minify(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cleanup(files, scope) {
|
||||||
|
const string = scope.split(' ').map(scope => `.${scope}`).join(' ');
|
||||||
|
for (const file of files) {
|
||||||
|
await replaceInFile(file, data => data
|
||||||
|
.replace(currentScopeRe, '') // remove scope comment
|
||||||
|
.replace(new RegExp(` *${string} ({[\\s\\S]*?})?`, 'g'), '') // replace classes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripComments(input) {
|
||||||
|
return input
|
||||||
|
.replace(/\/\*(.|\n)*?\*\//gm, '')
|
||||||
|
.split('\n')
|
||||||
|
.filter(line => line.trim().substr(0, 2) !== '//')
|
||||||
|
.join('\n');
|
||||||
|
}
|
291
client/uikit/build/scss.js
Normal file
291
client/uikit/build/scss.js
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
import NP from 'number-precision';
|
||||||
|
import {glob, read, write} from './util.js';
|
||||||
|
|
||||||
|
NP.enableBoundaryChecking(false);
|
||||||
|
|
||||||
|
const themeMixins = {};
|
||||||
|
const coreMixins = {};
|
||||||
|
const themeVar = {};
|
||||||
|
const coreVar = {};
|
||||||
|
|
||||||
|
/* template for the new components/mixins.scss file*/
|
||||||
|
const mixinTemplate = `//
|
||||||
|
// Component: Mixin
|
||||||
|
// Description: Defines mixins which are used across all components
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
// SVG
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
/// Replace \`$search\` with \`$replace\` in \`$string\`
|
||||||
|
/// @author Hugo Giraudel
|
||||||
|
/// @param {String} $string - Initial string
|
||||||
|
/// @param {String} $search - Substring to replace
|
||||||
|
/// @param {String} $replace ('') - New value
|
||||||
|
/// @return {String} - Updated string
|
||||||
|
@function str-replace($string, $search, $replace: '') {
|
||||||
|
$index: str-index($string, $search);
|
||||||
|
|
||||||
|
@if $index {
|
||||||
|
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin svg-fill($src, $color-default, $color-new){
|
||||||
|
|
||||||
|
$replace-src: str-replace($src, $color-default, $color-new) !default;
|
||||||
|
$replace-src: str-replace($replace-src, "#", "%23");
|
||||||
|
background-image: url(quote($replace-src));
|
||||||
|
}`;
|
||||||
|
|
||||||
|
/* template for the inverse components */
|
||||||
|
const inverseTemplate = ` @include hook-inverse-component-base();
|
||||||
|
@include hook-inverse-component-link();
|
||||||
|
@include hook-inverse-component-heading();
|
||||||
|
@include hook-inverse-component-divider();
|
||||||
|
@include hook-inverse-component-list();
|
||||||
|
@include hook-inverse-component-icon();
|
||||||
|
@include hook-inverse-component-form();
|
||||||
|
@include hook-inverse-component-button();
|
||||||
|
@include hook-inverse-component-grid();
|
||||||
|
@include hook-inverse-component-close();
|
||||||
|
@include hook-inverse-component-totop();
|
||||||
|
@include hook-inverse-component-badge();
|
||||||
|
@include hook-inverse-component-label();
|
||||||
|
@include hook-inverse-component-article();
|
||||||
|
@include hook-inverse-component-search();
|
||||||
|
@include hook-inverse-component-nav();
|
||||||
|
@include hook-inverse-component-navbar();
|
||||||
|
@include hook-inverse-component-subnav();
|
||||||
|
@include hook-inverse-component-breadcrumb();
|
||||||
|
@include hook-inverse-component-pagination();
|
||||||
|
@include hook-inverse-component-tab();
|
||||||
|
@include hook-inverse-component-slidenav();
|
||||||
|
@include hook-inverse-component-dotnav();
|
||||||
|
@include hook-inverse-component-accordion();
|
||||||
|
@include hook-inverse-component-iconnav();
|
||||||
|
@include hook-inverse-component-text();
|
||||||
|
@include hook-inverse-component-column();
|
||||||
|
@include hook-inverse-component-utility();`;
|
||||||
|
|
||||||
|
/* First Step: Go through all files */
|
||||||
|
for (const file of await glob('src/less/**/*.less')) {
|
||||||
|
|
||||||
|
const data = await read(file);
|
||||||
|
|
||||||
|
/* replace all Less stuff with SCSS */
|
||||||
|
let scssData = data.replace(/\/less\//g, '/scss/') // change less/ dir to scss/ on imports
|
||||||
|
.replace(/\.less/g, '.scss') // change .less extensions to .scss on imports
|
||||||
|
.replace(/@/g, '$') // convert variables
|
||||||
|
.replace(/(:[^'"]*?\([^'"]+?)\s*\/\s*([0-9.-]+)\)/g, (exp, m1, m2) => `${m1} * ${NP.round(1 / parseFloat(m2), 5)})`)
|
||||||
|
.replace(/--uk-[^\s]+: (\$[^\s]+);/g, (exp, name) => exp.replace(name, `#{${name}}`))
|
||||||
|
.replace(/\\\$/g, '\\@') // revert classes using the @ symbol
|
||||||
|
.replace(/ e\(/g, ' unquote(') // convert escape function
|
||||||
|
.replace(/\.([\w-]*)\s*\((.*)\)\s*{/g, '@mixin $1($2){') // hook -> mixins
|
||||||
|
.replace(/(\$[\w-]*)\s*:(.*);/g, '$1: $2 !default;') // make variables optional
|
||||||
|
.replace(/@mixin ([\w-]*)\s*\((.*)\)\s*{\s*}/g, '// @mixin $1($2){}') // comment empty mixins
|
||||||
|
.replace(/\.(hook[a-zA-Z\-\d]+)(\(\))?;/g, '@if(mixin-exists($1)) {@include $1();}') // hook calls surrounded by a mixin-exists
|
||||||
|
.replace(/\$(import|supports|media|font-face|page|-ms-viewport|keyframes|-webkit-keyframes|-moz-document)/g, '@$1') // replace valid '@' statements
|
||||||
|
.replace(/tint\((\$[\w-]+),\s([^)]*)\)/g, 'mix(white, $1, $2)') // replace Less function tint with mix
|
||||||
|
.replace(/fade\((\$[\w-]*), ([0-9]+)%\)/g, (match, p1, p2) => { return `rgba(${p1}, ${p2 / 100})`;}) // replace Less function fade with rgba
|
||||||
|
.replace(/fadeout\((\$[\w-]*), ([0-9]+)%\)/g, (match, p1, p2) => { return `fade-out(${p1}, ${p2 / 100})`;}) // replace Less function fadeout with fade-out
|
||||||
|
.replace(/\.svg-fill/g, '@include svg-fill') // include svg-fill mixin
|
||||||
|
.replace(/(.*):extend\((\.[\w-\\@]*) all\) when \((\$[\w-]*) = ([\w]+)\) {}/g, '@if ( $3 == $4 ) { $1 { @extend $2 !optional;} }') // update conditional extend and add !optional to ignore warnings
|
||||||
|
.replace(/(\.[\w-\\@]+)\s*when\s*\((\$[\w-]*)\s*=\s*(\w+)\)\s*{\s*@if\(mixin-exists\(([\w-]*)\)\) {@include\s([\w-]*)\(\);\s*}\s*}/g, '@if ($2 == $3) { $1 { @if (mixin-exists($4)) {@include $4();}}}') // update conditional hook
|
||||||
|
.replace(/(\.[\w-\\@]+)\s*when\s*\((\$[\w-]*)\s*=\s*(\w+)\)\s*({\s*.*?\s*})/gs, '@if ($2 == $3) {\n$1 $4\n}') // replace conditionals
|
||||||
|
.replace(/\${/g, '#{$') // string literals: from: /~"(.*)"/g, to: '#{"$1"}'
|
||||||
|
.replace(/[^(](-\$[\w-]*)/g, ' ($1)') // surround negative variables with brackets
|
||||||
|
.replace(/(--[\w-]+:\s*)~'([^']+)'/g, '$1$2') // string literals in custom properties
|
||||||
|
.replace(/~('[^']+')/g, 'unquote($1)'); // string literals: for real
|
||||||
|
|
||||||
|
/* File name of the current file */
|
||||||
|
const [filename] = file.split('/').pop().split('.less');
|
||||||
|
|
||||||
|
if (filename !== 'inverse') {
|
||||||
|
scssData = scssData.replace(/hook-inverse(?!-)/g, `hook-inverse-component-${filename}`);
|
||||||
|
} else {
|
||||||
|
const joinedHook = `@mixin hook-inverse(){\n${inverseTemplate}\n}\n`;
|
||||||
|
scssData = scssData.replace(/\*\//, '*/\n' + joinedHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get all the mixins and remove them from the file */
|
||||||
|
scssData = getMixinsFromFile(file, scssData);
|
||||||
|
|
||||||
|
/* get all Variables but not from the mixin.less file */
|
||||||
|
if (filename !== 'mixin') {
|
||||||
|
scssData = await getVariablesFromFile(file, scssData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename === 'uikit.theme') {
|
||||||
|
/* remove the theme import first place */
|
||||||
|
scssData = scssData.replace(/\/\/\n\/\/ Theme\n\/\/\n\n@import "theme\/_import.scss";/, '');
|
||||||
|
/* add uikit-mixins and uikit-variables include to the uikit.scss file and change order, to load theme files first */
|
||||||
|
scssData = scssData.replace(/\/\/ Core\n\/\//g, '// Theme\n//\n\n@import "theme/_import.scss";');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mixin.less needs to be fully replaced by the new mixin file*/
|
||||||
|
if (filename === 'mixin') {
|
||||||
|
scssData = mixinTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
await write(file.replace(/less/g, 'scss').replace('.theme.', '-theme.'), scssData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second Step write all new needed files for SASS */
|
||||||
|
|
||||||
|
/* write mixins into new file */
|
||||||
|
const mixins_theme = Object.keys(themeMixins).map(function (key) { return themeMixins[key]; });
|
||||||
|
await write('src/scss/mixins-theme.scss', mixins_theme.join('\n'));
|
||||||
|
|
||||||
|
const mixins_core = Object.keys(coreMixins).map(function (key) { return coreMixins[key]; });
|
||||||
|
await write('src/scss/mixins.scss', mixins_core.join('\n'));
|
||||||
|
|
||||||
|
/* write core variables */
|
||||||
|
const compactCoreVar = new Set();
|
||||||
|
Object.keys(coreVar).map(key => getAllDependencies(coreVar, key).forEach(dependency => compactCoreVar.add(dependency)));
|
||||||
|
|
||||||
|
await write('src/scss/variables.scss', Array.from(compactCoreVar).join('\n'));
|
||||||
|
|
||||||
|
/* write theme variables */
|
||||||
|
const compactThemeVar = new Set();
|
||||||
|
Object.keys(themeVar).map(key => getAllDependencies(themeVar, key).forEach(dependency => compactThemeVar.add(dependency)));
|
||||||
|
|
||||||
|
await write('src/scss/variables-theme.scss', Array.from(compactThemeVar).join('\n'));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* recursive function to get a dependencie Set which is ordered so that no depencies exist to a later on entry
|
||||||
|
* @return Set with all the dependencies.
|
||||||
|
*/
|
||||||
|
function getAllDependencies(allVariables, currentKey, dependencies = new Set()) {
|
||||||
|
|
||||||
|
if (!allVariables[currentKey].dependencies.length) {
|
||||||
|
|
||||||
|
dependencies.add(`${currentKey}: ${allVariables[currentKey].value}`);
|
||||||
|
return Array.from(dependencies);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
allVariables[currentKey].dependencies.forEach(dependecy => {
|
||||||
|
getAllDependencies(allVariables, dependecy, dependencies).forEach(newDependency => dependencies.add(newDependency));
|
||||||
|
});
|
||||||
|
|
||||||
|
dependencies.add(`${currentKey}: ${allVariables[currentKey].value}`);
|
||||||
|
return Array.from(dependencies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* function to extract all the mixins from a given file with its data.
|
||||||
|
* @return an updated data where the mixins have been removed.
|
||||||
|
*/
|
||||||
|
function getMixinsFromFile(file, data) {
|
||||||
|
|
||||||
|
/* Step 1: get all includes and insert them, so that at least empty mixins exist. */
|
||||||
|
let regex = /@include ([a-z0-9-]+)/g;
|
||||||
|
let match = regex.exec(data);
|
||||||
|
|
||||||
|
while (match) {
|
||||||
|
if (!(match[1] in themeMixins)) { themeMixins[match[1]] = `@mixin ${match[1]}(){}`; }
|
||||||
|
if (!(match[1] in coreMixins)) { coreMixins[match[1]] = `@mixin ${match[1]}(){}`; }
|
||||||
|
|
||||||
|
match = regex.exec(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 2: get all multiline mixins */
|
||||||
|
regex = /@mixin ([\w-]*)\s*\((.*)\)\s*{\n(\s+[\w\W]+?)(?=\n})\n}/g;
|
||||||
|
match = regex.exec(data);
|
||||||
|
|
||||||
|
while (match) {
|
||||||
|
[themeMixins[match[1]]] = match;
|
||||||
|
if (file.indexOf('theme/') < 0) {
|
||||||
|
[coreMixins[match[1]]] = match;
|
||||||
|
}
|
||||||
|
match = regex.exec(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 3: get all singleline mixins */
|
||||||
|
regex = /@mixin ([\w-]*)\s*\((.*)\)\s*{( [^\n]+)}/g;
|
||||||
|
match = regex.exec(data);
|
||||||
|
|
||||||
|
while (match) {
|
||||||
|
[themeMixins[match[1]]] = match;
|
||||||
|
if (file.indexOf('theme/') < 0) {
|
||||||
|
[coreMixins[match[1]]] = match;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = regex.exec(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 4: remove the mixins from the file, so that users can overwrite them in their custom code. */
|
||||||
|
return data
|
||||||
|
.replace(/@mixin ([\w-]*)\s*\((.*)\)\s*{\n(\s+[\w\W]+?)(?=\n})\n}/g, '')
|
||||||
|
.replace(/@mixin ([\w-]*)\s*\((.*)\)\s*{( [^\n]+)}/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* function to extract all the variables from a given file with its data.
|
||||||
|
* @return an updated data where the icons have been replaced by the actual SVG data.
|
||||||
|
*/
|
||||||
|
async function getVariablesFromFile(file, data) {
|
||||||
|
const regex = /(\$[\w-]*)\s*:\s*(.*);/g;
|
||||||
|
let match = regex.exec(data);
|
||||||
|
|
||||||
|
while (match) {
|
||||||
|
|
||||||
|
/* check if variable is a background icon, if so replace it directly by the SVG */
|
||||||
|
if (match[0].indexOf('../../images/backgrounds') >= 0) {
|
||||||
|
|
||||||
|
const iconregex = /(\$[\w-]+)\s*:\s*"\.\.\/\.\.\/images\/backgrounds\/([\w./-]+)" !default;/g;
|
||||||
|
const iconmatch = iconregex.exec(match[0]);
|
||||||
|
let svg = (await read(`src/images/backgrounds/${iconmatch[2]}`)).toString();
|
||||||
|
svg = `"${svg.replace(/\r?\n|\r/g, '%0A')
|
||||||
|
.replace(/"/g, '\'')
|
||||||
|
.replace(/\s/g, '%20')
|
||||||
|
.replace(/</g, '%3C')
|
||||||
|
.replace(/=/g, '%3D')
|
||||||
|
.replace(/'/g, '%22')
|
||||||
|
.replace(/:/g, '%3A')
|
||||||
|
.replace(/\//g, '%2F')
|
||||||
|
.replace(/>/g, '%3E')
|
||||||
|
.replace(/%3Csvg/, 'data:image/svg+xml;charset=UTF-8,%3Csvg')}"`;
|
||||||
|
|
||||||
|
/* add SVG to the coreVar and themeVar only if it is a theme file and make it optional */
|
||||||
|
if (file.indexOf('theme/') < 0) {
|
||||||
|
coreVar[iconmatch[1]] = {value: `${svg} !default;`, dependencies: []};
|
||||||
|
}
|
||||||
|
|
||||||
|
themeVar[iconmatch[1]] = {value: `${svg} !default;`, dependencies: []};
|
||||||
|
|
||||||
|
/* add SVG to the variable within the file itself as well */
|
||||||
|
const inlineSVG = `${iconmatch[1]}: ${svg} !default;`;
|
||||||
|
data = data.replace(match[0], inlineSVG);
|
||||||
|
|
||||||
|
/* when it is not an SVG add the variable and search for its dependencies */
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const variablesRegex = /(\$[\w-]+)/g;
|
||||||
|
let variablesMatch = variablesRegex.exec(match[2]);
|
||||||
|
const dependencies = [];
|
||||||
|
|
||||||
|
while (variablesMatch) {
|
||||||
|
dependencies.push(variablesMatch[1]);
|
||||||
|
variablesMatch = variablesRegex.exec(match[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add variables only to the core Variables if it is not a theme file */
|
||||||
|
if (file.indexOf('theme/') < 0) {
|
||||||
|
coreVar[match[1]] = {value: `${match[2]};`, dependencies: Array.from(dependencies)};
|
||||||
|
}
|
||||||
|
|
||||||
|
themeVar[match[1]] = {value: `${match[2]};`, dependencies: Array.from(dependencies)};
|
||||||
|
}
|
||||||
|
|
||||||
|
match = regex.exec(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
246
client/uikit/build/util.js
Normal file
246
client/uikit/build/util.js
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
import less from 'less';
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import pLimit from 'p-limit';
|
||||||
|
import globImport from 'glob';
|
||||||
|
import {optimize} from 'svgo';
|
||||||
|
import {promisify} from 'util';
|
||||||
|
import minimist from 'minimist';
|
||||||
|
import CleanCSS from 'clean-css';
|
||||||
|
import html from 'rollup-plugin-html';
|
||||||
|
import buble from '@rollup/plugin-buble';
|
||||||
|
import alias from '@rollup/plugin-alias';
|
||||||
|
import modify from 'rollup-plugin-modify';
|
||||||
|
import replace from '@rollup/plugin-replace';
|
||||||
|
import {basename, dirname, join} from 'path';
|
||||||
|
import {exec as execImport} from 'child_process';
|
||||||
|
import {rollup, watch as rollupWatch} from 'rollup';
|
||||||
|
import {minify as rollupMinify} from 'rollup-plugin-esbuild';
|
||||||
|
|
||||||
|
const limit = pLimit(Number(process.env.cpus || 2));
|
||||||
|
|
||||||
|
export const exec = promisify(execImport);
|
||||||
|
export const glob = promisify(globImport);
|
||||||
|
export const {pathExists, readJson} = fs;
|
||||||
|
|
||||||
|
export const banner = `/*! UIkit ${await getVersion()} | https://www.getuikit.com | (c) 2014 - ${new Date().getFullYear()} YOOtheme | MIT License */\n`;
|
||||||
|
export const validClassName = /[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/;
|
||||||
|
|
||||||
|
const argv = minimist(process.argv.slice(2));
|
||||||
|
|
||||||
|
argv._.forEach(arg => {
|
||||||
|
const tokens = arg.split('=');
|
||||||
|
argv[tokens[0]] = tokens[1] || true;
|
||||||
|
});
|
||||||
|
|
||||||
|
export const args = argv;
|
||||||
|
|
||||||
|
export function read(file) {
|
||||||
|
return fs.readFile(file, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function write(dest, data) {
|
||||||
|
|
||||||
|
const err = await fs.writeFile(dest, data);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
await logFile(dest);
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function logFile(file) {
|
||||||
|
const data = await read(file);
|
||||||
|
console.log(`${cyan(file)} ${getSize(data)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function minify(file) {
|
||||||
|
|
||||||
|
const {styles} = await limit(() => new CleanCSS({
|
||||||
|
advanced: false,
|
||||||
|
keepSpecialComments: 0,
|
||||||
|
rebase: false,
|
||||||
|
returnPromise: true
|
||||||
|
}).minify([file]));
|
||||||
|
|
||||||
|
await write(`${join(dirname(file), basename(file, '.css'))}.min.css`, styles);
|
||||||
|
|
||||||
|
return styles;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderLess(data, options) {
|
||||||
|
return limit(async () => (await less.render(data, options)).css);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function compile(file, dest, {external, globals, name, aliases, replaces} = {}) {
|
||||||
|
|
||||||
|
const minify = !args.nominify;
|
||||||
|
const debug = args.d || args.debug;
|
||||||
|
const watch = args.w || args.watch;
|
||||||
|
|
||||||
|
name = (name || '').replace(/[^\w]/g, '_');
|
||||||
|
|
||||||
|
const inputOptions = {
|
||||||
|
external,
|
||||||
|
input: file,
|
||||||
|
plugins: [
|
||||||
|
replace({
|
||||||
|
preventAssignment: true,
|
||||||
|
values: {
|
||||||
|
VERSION: `'${await getVersion()}'`,
|
||||||
|
...replaces
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
alias({
|
||||||
|
entries: {
|
||||||
|
'uikit-util': './src/js/util/index.js',
|
||||||
|
...aliases
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
html({
|
||||||
|
include: '**/*.svg',
|
||||||
|
htmlMinifierOptions: {
|
||||||
|
collapseWhitespace: true
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
buble({namedFunctionExpressions: false}),
|
||||||
|
modify({
|
||||||
|
find: /(>)\\n\s+|\\n\s+(<)/,
|
||||||
|
replace: (m, m1, m2) => `${m1 || ''} ${m2 || ''}`
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const outputOptions = {
|
||||||
|
globals,
|
||||||
|
banner,
|
||||||
|
format: 'umd',
|
||||||
|
amd: {id: `UIkit${name}`.toLowerCase()},
|
||||||
|
name: `UIkit${ucfirst(name)}`,
|
||||||
|
sourcemap: debug ? 'inline' : false
|
||||||
|
};
|
||||||
|
|
||||||
|
const output = [{
|
||||||
|
...outputOptions,
|
||||||
|
file: `${dest}.js`
|
||||||
|
}];
|
||||||
|
|
||||||
|
if (minify) {
|
||||||
|
output.push({
|
||||||
|
...outputOptions,
|
||||||
|
file: `${dest}.min.js`,
|
||||||
|
plugins: [minify ? rollupMinify() : undefined]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!watch) {
|
||||||
|
const bundle = await rollup(inputOptions);
|
||||||
|
|
||||||
|
for (const options of output) {
|
||||||
|
await limit(() => bundle.write(options));
|
||||||
|
logFile(options.file);
|
||||||
|
}
|
||||||
|
|
||||||
|
await bundle.close();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
console.log('UIkit is watching the files...');
|
||||||
|
|
||||||
|
const watcher = rollupWatch({
|
||||||
|
...inputOptions,
|
||||||
|
output
|
||||||
|
});
|
||||||
|
|
||||||
|
watcher.on('event', ({code, result, output, error}) => {
|
||||||
|
if (result) {
|
||||||
|
result.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
if (code === 'BUNDLE_END' && output) {
|
||||||
|
output.map(logFile);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watcher.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function icons(src) {
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'preset-default',
|
||||||
|
params: {
|
||||||
|
overrides: {
|
||||||
|
removeViewBox: false,
|
||||||
|
cleanupNumericValues: {
|
||||||
|
floatPrecision: 3
|
||||||
|
},
|
||||||
|
convertPathData: false,
|
||||||
|
convertShapeToPath: false,
|
||||||
|
mergePaths: false,
|
||||||
|
removeDimensions: false,
|
||||||
|
removeStyleElement: false,
|
||||||
|
removeScriptElement: false,
|
||||||
|
removeUnknownsAndDefaults: false,
|
||||||
|
removeUselessStrokeAndFill: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const files = await glob(src, {nosort: true});
|
||||||
|
const icons = await Promise.all(
|
||||||
|
files.map(file =>
|
||||||
|
limit(async () =>
|
||||||
|
(await optimize(await read(file), options)).data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return JSON.stringify(files.reduce((result, file, i) => {
|
||||||
|
result[basename(file, '.svg')] = icons[i];
|
||||||
|
return result;
|
||||||
|
}, {}), null, ' ');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function run(cmd, options) {
|
||||||
|
const {stdout, stderr} = await limit(() => exec(cmd, options));
|
||||||
|
|
||||||
|
stdout && console.log(stdout.trim());
|
||||||
|
stderr && console.log(stderr.trim());
|
||||||
|
|
||||||
|
return stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ucfirst(str) {
|
||||||
|
return str.length ? str.charAt(0).toUpperCase() + str.slice(1) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getVersion() {
|
||||||
|
return (await readJson('package.json')).version;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function replaceInFile(file, fn) {
|
||||||
|
await write(file, await fn(await read(file)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function cyan(str) {
|
||||||
|
return `\x1b[1m\x1b[36m${str}\x1b[39m\x1b[22m`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSize(data) {
|
||||||
|
return `${(data.length / 1024).toFixed(2)}kb`;
|
||||||
|
}
|
7
client/uikit/build/wrapper/component.js
Normal file
7
client/uikit/build/wrapper/component.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Component from 'component';
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined' && window.UIkit) {
|
||||||
|
window.UIkit.component(NAME, Component);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Component;
|
15
client/uikit/build/wrapper/icons.js
Normal file
15
client/uikit/build/wrapper/icons.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function plugin(UIkit) {
|
||||||
|
|
||||||
|
if (plugin.installed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIkit.icon.add(ICONS);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined' && window.UIkit) {
|
||||||
|
window.UIkit.use(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default plugin;
|
@ -11,7 +11,7 @@ kotlin {
|
|||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api "dev.inmo:micro_utils.repos.ktor.client:$microutils_version"
|
api libs.microutils.repos.ktor.client
|
||||||
api "io.ktor:ktor-client-auth:$ktor_version"
|
api "io.ktor:ktor-client-auth:$ktor_version"
|
||||||
api "io.ktor:ktor-client-logging:$ktor_version"
|
api "io.ktor:ktor-client-logging:$ktor_version"
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api "dev.inmo:micro_utils.common:$microutils_version"
|
api libs.microutils.common
|
||||||
api "dev.inmo:micro_utils.serialization.typed_serializer:$microutils_version"
|
api libs.microutils.serialization.typedserializer
|
||||||
api "io.insert-koin:koin-core:$koin_version"
|
api "io.insert-koin:koin-core:$koin_version"
|
||||||
api "com.benasher44:uuid:$uuid_version"
|
api "com.benasher44:uuid:$uuid_version"
|
||||||
api "com.soywiz.korlibs.klock:klock:$klock_version"
|
api "com.soywiz.korlibs.klock:klock:$klock_version"
|
||||||
|
52
features/common/common/create_version_file.gradle
Normal file
52
features/common/common/create_version_file.gradle
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
String versionLine() { return " const val project = \"$project.version\"" }
|
||||||
|
File versionFile() { return project.file("src/commonMain/kotlin/dev/inmo/postssystem/features/common/common/Version.kt") }
|
||||||
|
|
||||||
|
void createVersionFile() {
|
||||||
|
String versionLine = versionLine()
|
||||||
|
File versionFile = versionFile()
|
||||||
|
versionFile.parentFile.mkdirs()
|
||||||
|
if (versionFile.exists()) versionFile.delete()
|
||||||
|
versionFile.createNewFile()
|
||||||
|
versionFile.text = """package dev.inmo.postssystem.features.common.common
|
||||||
|
|
||||||
|
/*
|
||||||
|
* THIS FILE HAS BEEN CREATED AUTOMATICALLY.
|
||||||
|
* DO NOT EDIT THIS FILE, ITS CONTENT WILL BE OVERWRITTEN
|
||||||
|
* WITH ANY NEW BUILD
|
||||||
|
*/
|
||||||
|
object Version {
|
||||||
|
$versionLine
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean isVersionFileUpToDate() {
|
||||||
|
String versionLine = versionLine()
|
||||||
|
File versionFile = versionFile()
|
||||||
|
|
||||||
|
boolean upToDate = false
|
||||||
|
if (versionFile.exists()) {
|
||||||
|
versionFile.withReader { reader ->
|
||||||
|
String line
|
||||||
|
while ((line = reader.readLine()) != null && !upToDate) {
|
||||||
|
upToDate = line == versionLine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return upToDate
|
||||||
|
}
|
||||||
|
|
||||||
|
task createVersionFile {
|
||||||
|
doLast {
|
||||||
|
createVersionFile()
|
||||||
|
}
|
||||||
|
outputs.upToDateWhen {
|
||||||
|
isVersionFileUpToDate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!isVersionFileUpToDate()) {
|
||||||
|
createVersionFile()
|
||||||
|
}
|
@ -10,9 +10,9 @@ kotlin {
|
|||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api "dev.inmo:micro_utils.repos.exposed:$microutils_version"
|
api libs.microutils.repos.exposed
|
||||||
api "dev.inmo:micro_utils.repos.ktor.server:$microutils_version"
|
api libs.microutils.repos.ktor.server
|
||||||
api "dev.inmo:micro_utils.ktor.server:$microutils_version"
|
api libs.microutils.ktor.server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jvmMain {
|
jvmMain {
|
||||||
|
@ -12,7 +12,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api project(":postssystem.features.content.common")
|
api project(":postssystem.features.content.common")
|
||||||
api "dev.inmo:micro_utils.mime_types:$microutils_version"
|
api libs.microutils.mimetypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ kotlin {
|
|||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api "dev.inmo:micro_utils.mime_types:$microutils_version"
|
api libs.microutils.mimetypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ kotlin {
|
|||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api "dev.inmo:micro_utils.mime_types:$microutils_version"
|
api libs.microutils.mimetypes
|
||||||
api "dev.inmo:micro_utils.repos.common:$microutils_version"
|
api libs.microutils.repos.common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,12 @@ kotlin {
|
|||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api "dev.inmo:micro_utils.repos.common:$microutils_version"
|
api libs.microutils.repos.common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jvmMain {
|
jvmMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api "dev.inmo:micro_utils.repos.exposed:$microutils_version"
|
api libs.microutils.repos.exposed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,14 @@ kotlin_version=1.6.10
|
|||||||
kotlin_serialisation_core_version=1.3.2
|
kotlin_serialisation_core_version=1.3.2
|
||||||
|
|
||||||
koin_version=3.1.2
|
koin_version=3.1.2
|
||||||
microutils_version=0.9.4
|
|
||||||
ktor_version=1.6.7
|
ktor_version=1.6.7
|
||||||
logback_version=1.2.10
|
logback_version=1.2.10
|
||||||
uuid_version=0.3.1
|
uuid_version=0.3.1
|
||||||
klock_version=2.4.12
|
klock_version=2.5.2
|
||||||
|
|
||||||
tgbotapi_version=0.38.3
|
|
||||||
|
|
||||||
# Server
|
# Server
|
||||||
|
|
||||||
kotlin_exposed_version=0.37.2
|
kotlin_exposed_version=0.37.3
|
||||||
psql_version=42.3.0
|
psql_version=42.3.0
|
||||||
|
|
||||||
# JS
|
# JS
|
||||||
|
@ -1,13 +1,35 @@
|
|||||||
[versions]
|
[versions]
|
||||||
|
|
||||||
jsuikit = "0.0.27"
|
kotlin = "1.6.10"
|
||||||
compose = "1.0.1"
|
kotlin-serialization = "1.3.2"
|
||||||
microutils = "0.9.4"
|
jsuikit = "0.0.41"
|
||||||
|
compose = "1.1.0"
|
||||||
|
microutils = "0.9.9"
|
||||||
|
tgbotapi = "0.38.6"
|
||||||
|
ktor = "1.6.7"
|
||||||
|
exposed = "0.37.3"
|
||||||
|
psql = "42.3.0"
|
||||||
|
|
||||||
|
android-dexcount = "3.0.1"
|
||||||
|
android-junit = "4.12"
|
||||||
|
android-test-junit = "1.1.2"
|
||||||
|
android-espresso-core = "3.3.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
|
||||||
|
kotlin-std = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
|
||||||
|
kotlin-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlin-serialization" }
|
||||||
|
kotlin-serialization-properties = { module = "org.jetbrains.kotlinx:kotlinx-serialization-properties", version.ref = "kotlin-serialization" }
|
||||||
|
|
||||||
jsuikit = { module = "dev.inmo:kjsuikit", version.ref = "jsuikit" }
|
jsuikit = { module = "dev.inmo:kjsuikit", version.ref = "jsuikit" }
|
||||||
|
|
||||||
|
postgresql = { module = "org.postgresql:postgresql", version.ref = "psql" }
|
||||||
|
|
||||||
|
exposed-jdbs = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" }
|
||||||
|
|
||||||
|
ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
|
||||||
|
ktor-websockets = { module = "io.ktor:ktor-websockets", version.ref = "ktor" }
|
||||||
|
|
||||||
microutils-common = { module = "dev.inmo:micro_utils.common", version.ref = "microutils" }
|
microutils-common = { module = "dev.inmo:micro_utils.common", version.ref = "microutils" }
|
||||||
microutils-pagination-common = { module = "dev.inmo:micro_utils.pagination.common", version.ref = "microutils" }
|
microutils-pagination-common = { module = "dev.inmo:micro_utils.pagination.common", version.ref = "microutils" }
|
||||||
microutils-fsm-common = { module = "dev.inmo:micro_utils.fsm.common", version.ref = "microutils" }
|
microutils-fsm-common = { module = "dev.inmo:micro_utils.fsm.common", version.ref = "microutils" }
|
||||||
@ -19,8 +41,14 @@ microutils-repos-ktor-server = { module = "dev.inmo:micro_utils.repos.ktor.serve
|
|||||||
microutils-repos-exposed = { module = "dev.inmo:micro_utils.repos.exposed", version.ref = "microutils" }
|
microutils-repos-exposed = { module = "dev.inmo:micro_utils.repos.exposed", version.ref = "microutils" }
|
||||||
microutils-mimetypes = { module = "dev.inmo:micro_utils.mime_types", version.ref = "microutils" }
|
microutils-mimetypes = { module = "dev.inmo:micro_utils.mime_types", version.ref = "microutils" }
|
||||||
microutils-coroutines = { module = "dev.inmo:micro_utils.coroutines", version.ref = "microutils" }
|
microutils-coroutines = { module = "dev.inmo:micro_utils.coroutines", version.ref = "microutils" }
|
||||||
|
microutils-ktor-server = { module = "dev.inmo:micro_utils.ktor.server", version.ref = "microutils" }
|
||||||
microutils-serialization-typedserializer = { module = "dev.inmo:micro_utils.serialization.typed_serializer", version.ref = "microutils" }
|
microutils-serialization-typedserializer = { module = "dev.inmo:micro_utils.serialization.typed_serializer", version.ref = "microutils" }
|
||||||
|
|
||||||
|
tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" }
|
||||||
|
|
||||||
|
androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "android-test-junit" }
|
||||||
|
androidx-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "android-espresso-core" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
|
|
||||||
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
|
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,4 +1,4 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
@ -20,6 +20,13 @@ kotlin {
|
|||||||
implementation kotlin('test-annotations-common')
|
implementation kotlin('test-annotations-common')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
androidTest {
|
||||||
|
dependencies {
|
||||||
|
implementation kotlin('test-junit')
|
||||||
|
implementation libs.androidx.test.junit
|
||||||
|
implementation libs.androidx.espresso
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('stdlib')
|
implementation libs.kotlin.std
|
||||||
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_core_version"
|
api libs.kotlin.serialization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commonTest {
|
commonTest {
|
||||||
@ -40,8 +40,8 @@ kotlin {
|
|||||||
androidTest {
|
androidTest {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('test-junit')
|
implementation kotlin('test-junit')
|
||||||
implementation "androidx.test.ext:junit:$test_ext_junit_version"
|
implementation libs.androidx.test.junit
|
||||||
implementation "androidx.test.espresso:espresso-core:$espresso_core"
|
implementation libs.androidx.espresso
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
prepare_client.sh
Executable file
26
prepare_client.sh
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function assert_success() {
|
||||||
|
"${@}"
|
||||||
|
local status=${?}
|
||||||
|
if [ ${status} -ne 0 ]; then
|
||||||
|
send_notification "### Error ${status} at: ${BASH_LINENO[*]} ###"
|
||||||
|
exit ${status}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
rootPath="`pwd`"
|
||||||
|
localPath="$rootPath/local/"
|
||||||
|
|
||||||
|
mkdir "$localPath"
|
||||||
|
assert_success cd "$localPath"
|
||||||
|
|
||||||
|
assert_success git clone https://github.com/uikit/uikit.git
|
||||||
|
assert_success cd uikit
|
||||||
|
assert_success git checkout 4f815b6482fb93c98452c857b7a9a1450fecd660 # https://github.com/uikit/uikit/releases/tag/v3.11.1
|
||||||
|
assert_success cd -
|
||||||
|
|
||||||
|
assert_success cp -r "uikit/dist" "uikit/build" "uikit/tests" "$rootPath/client/uikit/"
|
||||||
|
assert_success cd "$rootPath"
|
||||||
|
|
||||||
|
rm -rf "$localPath/uikit"
|
@ -27,10 +27,10 @@ dependencies {
|
|||||||
|
|
||||||
api project(":postssystem.targets.telegram.publication.server")
|
api project(":postssystem.targets.telegram.publication.server")
|
||||||
|
|
||||||
api "io.ktor:ktor-server-netty:$ktor_version"
|
api libs.ktor.server.netty
|
||||||
api "io.ktor:ktor-websockets:$ktor_version"
|
api libs.ktor.websockets
|
||||||
api "org.jetbrains.exposed:exposed-jdbc:$kotlin_exposed_version"
|
api libs.exposed.jdbs
|
||||||
api "org.postgresql:postgresql:$psql_version"
|
api libs.postgresql
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api project(":postssystem.features.posts.common")
|
api project(":postssystem.features.posts.common")
|
||||||
api "dev.inmo:micro_utils.repos.common:$microutils_version"
|
api libs.microutils.repos.common
|
||||||
api "dev.inmo:micro_utils.repos.ktor.client:$microutils_version"
|
api libs.microutils.repos.ktor.client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ kotlin {
|
|||||||
api project(":postssystem.features.content.server")
|
api project(":postssystem.features.content.server")
|
||||||
api project(":postssystem.features.posts.server")
|
api project(":postssystem.features.posts.server")
|
||||||
api project(":postssystem.features.users.server")
|
api project(":postssystem.features.users.server")
|
||||||
api "dev.inmo:micro_utils.common:$microutils_version"
|
api libs.microutils.common
|
||||||
api "org.jetbrains.kotlinx:kotlinx-serialization-properties:$kotlin_serialisation_core_version"
|
api libs.kotlin.serialization.properties
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ kotlin {
|
|||||||
api project(":postssystem.features.content.binary.server")
|
api project(":postssystem.features.content.binary.server")
|
||||||
api project(":postssystem.features.content.text.server")
|
api project(":postssystem.features.content.text.server")
|
||||||
|
|
||||||
api "dev.inmo:tgbotapi:$tgbotapi_version"
|
api libs.tgbotapi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user