fix(switch to unified package for cloudly + api + cli): update
This commit is contained in:
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/cloudly',
|
||||
version: '1.0.215',
|
||||
description: 'A cloud manager utilizing Docker Swarmkit, designed for operations on Cloudron, and supports various cloud platforms like DigitalOcean, Hetzner Cloud, and Cloudflare.'
|
||||
version: '1.0.216',
|
||||
description: 'A cloud manager leveraging Docker Swarmkit for multi-cloud operations including DigitalOcean, Hetzner Cloud, and Cloudflare, with integration support and robust configuration management system.'
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import * as plugins from './cloudly.plugins.js';
|
||||
import { CloudlyConfig } from './cloudly.classes.config.js';
|
||||
import * as plugins from './plugins.js';
|
||||
import { CloudlyConfig } from './classes.config.js';
|
||||
|
||||
// interfaces
|
||||
import {} from '@tsclass/tsclass';
|
||||
|
||||
// Cloudly mods
|
||||
import { CloudlyInfo } from './cloudly.classes.cloudlyinfo.js';
|
||||
import { CloudlyServer } from './cloudly.classes.server.js';
|
||||
import { CloudlyInfo } from './classes.cloudlyinfo.js';
|
||||
import { CloudlyServer } from './classes.server.js';
|
||||
|
||||
// connectors
|
||||
import { CloudflareConnector } from './connector.cloudflare/connector.js';
|
||||
@ -17,7 +17,6 @@ import { MongodbConnector } from './connector.mongodb/connector.js';
|
||||
import { CloudlyCoreflowManager } from './manager.coreflow/coreflowmanager.js';
|
||||
import { ClusterManager } from './manager.cluster/clustermanager.js';
|
||||
import { CloudlyTaskmanager } from './manager.task/taskmanager.js';
|
||||
import { CloudlyVersionManager } from './manager.version/versionmanager.js';
|
||||
import { CloudlySecretManager } from './manager.secret/classes.secretmanager.js'
|
||||
import { CloudlyServerManager } from './manager.server/servermanager.js';
|
||||
import { ExternalApiManager } from './manager.status/statusmanager.js';
|
||||
@ -55,7 +54,6 @@ export class Cloudly {
|
||||
public externalApiManager: ExternalApiManager;
|
||||
public imageManager: ImageManager;
|
||||
public taskManager: CloudlyTaskmanager;
|
||||
public versionManager: CloudlyVersionManager;
|
||||
public serverManager: CloudlyServerManager;
|
||||
|
||||
private readyDeferred = new plugins.smartpromise.Deferred();
|
||||
@ -79,7 +77,6 @@ export class Cloudly {
|
||||
this.externalApiManager = new ExternalApiManager(this);
|
||||
this.imageManager = new ImageManager(this);
|
||||
this.taskManager = new CloudlyTaskmanager(this);
|
||||
this.versionManager = new CloudlyVersionManager(this);
|
||||
this.secretManager = new CloudlySecretManager(this);
|
||||
this.serverManager = new CloudlyServerManager(this);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from './cloudly.plugins.js';
|
||||
import * as paths from './cloudly.paths.js';
|
||||
import * as plugins from './plugins.js';
|
||||
import * as paths from './paths.js';
|
||||
import { Cloudly } from './index.js';
|
||||
|
||||
export class CloudlyInfo {
|
@ -1,7 +1,7 @@
|
||||
import * as plugins from './cloudly.plugins.js';
|
||||
import * as paths from './cloudly.paths.js';
|
||||
import * as plugins from './plugins.js';
|
||||
import * as paths from './paths.js';
|
||||
import { logger } from './cloudly.logging.js';
|
||||
import type { Cloudly } from './cloudly.classes.cloudly.js';
|
||||
import type { Cloudly } from './classes.cloudly.js';
|
||||
|
||||
/**
|
||||
* the main cloudly config
|
@ -1,6 +1,6 @@
|
||||
import * as plugins from './cloudly.plugins.js';
|
||||
import * as paths from './cloudly.paths.js';
|
||||
import { Cloudly } from './cloudly.classes.cloudly.js';
|
||||
import * as plugins from './plugins.js';
|
||||
import * as paths from './paths.js';
|
||||
import { Cloudly } from './classes.cloudly.js';
|
||||
import { logger } from './cloudly.logging.js';
|
||||
|
||||
/**
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from './cloudly.plugins.js';
|
||||
import * as paths from './cloudly.paths.js';
|
||||
import * as plugins from './plugins.js';
|
||||
import * as paths from './paths.js';
|
||||
|
||||
export const logger = new plugins.smartlog.Smartlog({
|
||||
logContext: {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
/**
|
||||
* the portion of Cloudflare responsible
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
export class LetsencryptConnector {
|
||||
private cloudlyRef: Cloudly;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
export class MongodbConnector {
|
||||
// INSTANCE
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
// Create an array to hold 10 ISecretGroup objects
|
||||
const demoSecretGroups: plugins.servezoneInterfaces.data.ISecretGroup[] = [];
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import type { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
export const installDemoData = async (cloudlyRef: Cloudly) => {
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import * as early from '@push.rocks/early';
|
||||
early.start('cloudly');
|
||||
import * as plugins from './cloudly.plugins.js';
|
||||
import * as paths from './cloudly.paths.js';
|
||||
import { Cloudly } from './cloudly.classes.cloudly.js';
|
||||
import * as plugins from './plugins.js';
|
||||
import * as paths from './paths.js';
|
||||
import { Cloudly } from './classes.cloudly.js';
|
||||
import { logger } from './cloudly.logging.js';
|
||||
const cloudlyQenv = new plugins.qenv.Qenv(paths.packageDir, paths.nogitDir, true);
|
||||
early.stop();
|
||||
|
17
ts/manager.auth/classes.authmanager.ts
Normal file
17
ts/manager.auth/classes.authmanager.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import type { Cloudly } from '../classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Authorization } from './classes.authorization.js';
|
||||
import { User } from './classes.user.js';
|
||||
|
||||
export class AuthManager {
|
||||
cloudlyRef: Cloudly
|
||||
public get db() {
|
||||
return this.cloudlyRef.mongodbConnector.smartdataDb;
|
||||
}
|
||||
public CUser = plugins.smartdata.setDefaultManagerForDoc(this, User);
|
||||
public CAuthorization = plugins.smartdata.setDefaultManagerForDoc(this, Authorization);
|
||||
|
||||
constructor(cloudlyRef: Cloudly) {
|
||||
this.cloudlyRef = cloudlyRef;
|
||||
}
|
||||
}
|
6
ts/manager.auth/classes.authorization.ts
Normal file
6
ts/manager.auth/classes.authorization.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
@plugins.smartdata.managed()
|
||||
export class Authorization extends plugins.smartdata.SmartDataDbDoc<Authorization, Authorization> {
|
||||
|
||||
}
|
6
ts/manager.auth/classes.user.ts
Normal file
6
ts/manager.auth/classes.user.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
@plugins.smartdata.managed()
|
||||
export class User extends plugins.smartdata.SmartDataDbDoc<User, User> {
|
||||
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
/*
|
||||
* cluster defines a swarmkit cluster
|
||||
*/
|
||||
@plugins.smartdata.Manager()
|
||||
@plugins.smartdata.managed()
|
||||
export class Cluster extends plugins.smartdata.SmartDataDbDoc<Cluster, plugins.servezoneInterfaces.data.ICluster> {
|
||||
// STATIC
|
||||
public static async fromConfigObject(
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as paths from '../cloudly.paths.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as paths from '../paths.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
import { logger } from '../cloudly.logging.js';
|
||||
|
||||
import { Cluster } from './cluster.js';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
/**
|
||||
* in charge of talking to coreflow services on clusters
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import type { ImageManager } from './classes.imagemanager.js';
|
||||
|
||||
@plugins.smartdata.Manager()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import type { Cloudly } from '../classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
import { Image } from './classes.image.js';
|
||||
|
||||
@ -49,11 +49,14 @@ export class ImageManager {
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_PushImage>('pushImage', async (reqArg) => {
|
||||
const pushStream = reqArg.imageStream;
|
||||
return {}
|
||||
})
|
||||
)
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_PushImage>(
|
||||
'pushImage',
|
||||
async (reqArg) => {
|
||||
const pushStream = reqArg.imageStream;
|
||||
return {};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_PullImage>(
|
||||
@ -62,13 +65,13 @@ export class ImageManager {
|
||||
const image = await this.CImage.getInstance({
|
||||
data: {
|
||||
name: reqArg.name,
|
||||
}
|
||||
},
|
||||
});
|
||||
const imageVersion = null;
|
||||
const imageVirtualStream = new plugins.typedrequest.VirtualStream();
|
||||
return {
|
||||
imageStream: imageVirtualStream,
|
||||
}
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
@ -82,7 +85,7 @@ export class ImageManager {
|
||||
this.cloudlyRef.config.data.s3Descriptor
|
||||
);
|
||||
const bucket = await this.smartbucketInstance.getBucketByName('cloudly-test');
|
||||
await bucket.fastStore('test/test.txt', 'hello');
|
||||
await bucket.fastPut({ path: 'test/test.txt', contents: 'hello' });
|
||||
}
|
||||
|
||||
public async createImage(nameArg: string) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
/**
|
||||
* takes care of receiving and providing logs
|
||||
|
@ -1,7 +1,7 @@
|
||||
// a secret bundle is a set of secrets ready to be used in a project.
|
||||
// it bundles secretgroups
|
||||
import { SecretGroup } from './classes.secretgroup.js';
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
@plugins.smartdata.Manager()
|
||||
export class SecretBundle extends plugins.smartdata.SmartDataDbDoc<
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* a secretgroup is a set of secrets for different environments.
|
||||
*/
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
@plugins.smartdata.Manager()
|
||||
export class SecretGroup extends plugins.smartdata.SmartDataDbDoc<
|
||||
|
@ -1,9 +1,9 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as paths from '../cloudly.paths.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import * as paths from '../paths.js';
|
||||
import { SecretBundle } from './classes.secretbundle.js';
|
||||
import { SecretGroup } from './classes.secretgroup.js';
|
||||
import { logger } from '../cloudly.logging.js';
|
||||
import type { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import type { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
/**
|
||||
* The `ConfigVault` class provides methods for reading and writing configuration data to a file.
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
/*
|
||||
* cluster defines a swarmkit cluster
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
import { Cluster } from '../manager.cluster/cluster.js';
|
||||
import { Server } from './server.js';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../index.js';
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
import * as plugins from '../plugins.js';
|
||||
import { Cloudly } from '../classes.cloudly.js';
|
||||
|
||||
import { logger } from '../cloudly.logging.js';
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
|
||||
/*
|
||||
A container version is managed by the versionmanager
|
||||
*/
|
||||
@plugins.smartdata.Manager()
|
||||
export class ContainerVersion
|
||||
extends plugins.smartdata.SmartDataDbDoc<ContainerVersion, unknown>
|
||||
implements plugins.servezoneInterfaces.data.IContainerVersionData
|
||||
{
|
||||
public static async fromIVersionData(
|
||||
dataArg: plugins.servezoneInterfaces.data.IContainerVersionData
|
||||
) {
|
||||
const containerVersionInstance = new ContainerVersion();
|
||||
containerVersionInstance.id = plugins.smartunique.shortId();
|
||||
Object.assign(containerVersionInstance, dataArg);
|
||||
return containerVersionInstance;
|
||||
}
|
||||
|
||||
@plugins.smartdata.unI()
|
||||
public id: string;
|
||||
|
||||
@plugins.smartdata.svDb()
|
||||
public dockerImageUrl: string;
|
||||
|
||||
@plugins.smartdata.svDb()
|
||||
public dockerImageVersion: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
import * as plugins from '../cloudly.plugins.js';
|
||||
|
||||
import { ContainerVersion } from './containerversion.js';
|
||||
import { Cloudly } from '../cloudly.classes.cloudly.js';
|
||||
|
||||
export class CloudlyVersionManager {
|
||||
// INSTANCE
|
||||
public cloudlyRef: Cloudly;
|
||||
public get db() {
|
||||
return this.cloudlyRef.mongodbConnector.smartdataDb;
|
||||
}
|
||||
public typedRouter = new plugins.typedrequest.TypedRouter();
|
||||
|
||||
// connected classes
|
||||
public CContainerVersion = plugins.smartdata.setDefaultManagerForDoc(this, ContainerVersion);
|
||||
|
||||
constructor(cloudlyRefArg: Cloudly) {
|
||||
this.cloudlyRef = cloudlyRefArg;
|
||||
this.cloudlyRef.typedrouter.addTypedRouter(this.typedRouter);
|
||||
// get version
|
||||
this.typedRouter.addTypedHandler<plugins.servezoneInterfaces.requests.version.IRequest_Any_Cloudly_VersionManager_GetLatestContainerVersion>(
|
||||
new plugins.typedrequest.TypedHandler(
|
||||
'getLatestContainerVersion',
|
||||
async (typedRequestData) => {
|
||||
const containerVersionGet: ContainerVersion =
|
||||
await ContainerVersion.getInstance<ContainerVersion>({
|
||||
dockerImageUrl: typedRequestData.dockerImageUrl,
|
||||
});
|
||||
return {
|
||||
dockerImageUrl: containerVersionGet.dockerImageUrl,
|
||||
dockerImageVersion: containerVersionGet.dockerImageVersion,
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// update version
|
||||
this.typedRouter.addTypedHandler<plugins.servezoneInterfaces.requests.version.IRequest_Any_Cloudly_VersionManager_InformCloudlyAboutNewContainerVersion>(
|
||||
new plugins.typedrequest.TypedHandler(
|
||||
'informCloudlyAboutNewContainerVersion',
|
||||
async (dataArg) => {
|
||||
console.log(`Got a container version announcement! "${dataArg.dockerImageUrl}"`);
|
||||
let containerVersion: ContainerVersion =
|
||||
await ContainerVersion.getInstance<ContainerVersion>({
|
||||
dockerImageUrl: dataArg.dockerImageUrl,
|
||||
});
|
||||
|
||||
if (containerVersion) {
|
||||
containerVersion.dockerImageVersion = dataArg.dockerImageVersion;
|
||||
await containerVersion.save();
|
||||
} else {
|
||||
containerVersion = await ContainerVersion.fromIVersionData(dataArg);
|
||||
await containerVersion.save();
|
||||
}
|
||||
|
||||
// lets push this info to the relevant clusters
|
||||
const clusters = await this.cloudlyRef.clusterManager.getAllClusters();
|
||||
let foundServices: plugins.servezoneInterfaces.data.IService;
|
||||
let relevantClusterIdentifier: plugins.servezoneInterfaces.data.IClusterIdentifier;
|
||||
for (const clusterArg of clusters) {
|
||||
console.log(clusterArg);
|
||||
for (const serviceArg of await clusterArg.getServices()) {
|
||||
if (serviceArg.image === containerVersion.dockerImageUrl) {
|
||||
foundServices = serviceArg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundServices) {
|
||||
relevantClusterIdentifier = {
|
||||
clusterName: clusterArg.data.name,
|
||||
secretKey: clusterArg.data.secretKey,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!relevantClusterIdentifier) {
|
||||
console.log('no cluster found that needs to update');
|
||||
return {};
|
||||
} else {
|
||||
console.log('found relevant cluster identifier:');
|
||||
console.log(relevantClusterIdentifier);
|
||||
}
|
||||
|
||||
const targetConnection =
|
||||
await this.cloudlyRef.server.typedsocketServer.findTargetConnection(
|
||||
async (connectionArg) => {
|
||||
const identityTag = await connectionArg.getTagById('identity');
|
||||
if (!identityTag) {
|
||||
return false;
|
||||
}
|
||||
const result =
|
||||
plugins.smartjson.stringify(identityTag.payload) ===
|
||||
plugins.smartjson.stringify(relevantClusterIdentifier);
|
||||
return result;
|
||||
}
|
||||
);
|
||||
|
||||
if (targetConnection) {
|
||||
console.log(`the relevant cluster is connected and is now being informed.`);
|
||||
const informCoreflowTR =
|
||||
this.cloudlyRef.server.typedsocketServer.createTypedRequest<plugins.servezoneInterfaces.requests.version.IRequest_Cloudly_Coreflow_VersionManager_InformCoreflowAboutNewContainerVersion>(
|
||||
'informCoreflowAboutNewContainerVersion',
|
||||
targetConnection
|
||||
);
|
||||
informCoreflowTR.fire({
|
||||
dockerImageUrl: containerVersion.dockerImageUrl,
|
||||
dockerImageVersion: containerVersion.dockerImageVersion,
|
||||
});
|
||||
} else {
|
||||
console.log('the relevant cluster is not connected at this time.');
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// lets support the servezone standard
|
||||
this.typedRouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.IRequest_InformAboutNewContainerImage>(
|
||||
'servezonestandard_InformAboutNewContainerVersion',
|
||||
async (dataArg) => {
|
||||
const result =
|
||||
await this.typedRouter.routeAndAddResponse<plugins.servezoneInterfaces.requests.version.IRequest_Any_Cloudly_VersionManager_InformCloudlyAboutNewContainerVersion>(
|
||||
{
|
||||
method: 'informCloudlyAboutNewContainerVersion',
|
||||
request: {
|
||||
dockerImageUrl: dataArg.containerImageInfo.registryUrl,
|
||||
dockerImageVersion: dataArg.containerImageInfo.version,
|
||||
},
|
||||
response: null
|
||||
},
|
||||
true
|
||||
);
|
||||
return result.response;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets all versions
|
||||
*/
|
||||
public async getAllVersions() {
|
||||
const result = await ContainerVersion.getInstances<ContainerVersion>({});
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import * as plugins from './cloudly.plugins.js';
|
||||
import * as plugins from './plugins.js';
|
||||
|
||||
export const packageDir = plugins.path.join(plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), '../');
|
||||
export const nogitDir = plugins.path.join(packageDir, '.nogit/');
|
Reference in New Issue
Block a user