@gluestack-v2/glue-plugin-sdk
Version:
Gluestack V2 Service SDK Plugin
271 lines (270 loc) • 14.4 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "path", "@gluestack-v2/framework-cli/build/plugin/BaseGluestackPluginInstance", "fs", "child_process"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PluginInstance = void 0;
const path_1 = require("path");
const BaseGluestackPluginInstance_1 = __importDefault(require("@gluestack-v2/framework-cli/build/plugin/BaseGluestackPluginInstance"));
const fs_1 = __importStar(require("fs"));
const child_process_1 = require("child_process");
const dotEnvPath = (0, path_1.join)(process.cwd(), '.env');
class PluginInstance extends BaseGluestackPluginInstance_1.default {
constructor(app, callerPlugin, name, gluePluginStore, installationPath) {
super(app, callerPlugin, name, gluePluginStore, installationPath);
}
init() {
//
}
destroy() {
//
}
getSourcePath() {
return `${process.cwd()}/node_modules/${this.callerPlugin.getName()}/template`;
}
getDestinationPath() {
return (0, path_1.join)(process.cwd(), '.glue', '__generated__', 'packages', this.getName());
}
createPackageByName(name, configName) {
return __awaiter(this, void 0, void 0, function* () {
const packagePath = yield this.app.createPackage(name, (0, path_1.join)(this.callerPlugin.getPackagePath(), 'sdk'));
yield this.app.replaceTemplateValues((0, path_1.join)(packagePath, 'src', 'index.ts'), 'UPDATECONFIGTYPE', configName);
//@ts-ignore
this.callerPlugin.setGeneratedSDKPaths(packagePath);
return packagePath;
});
}
build() {
return __awaiter(this, void 0, void 0, function* () {
// @ts-ignore
this.callerPlugin.resetGeneratedSDKPaths();
// @ts-ignore
yield this.callerPlugin.createConfigPackage('server',
// @ts-ignore
this.callerPlugin.getConfigPath(),
// @ts-ignore
this.callerPlugin.getGeneratedConfigPath('server'), this);
// @ts-ignore
yield this.callerPlugin.createConfigPackage('client',
// @ts-ignore
this.callerPlugin.getConfigPath(),
// @ts-ignore
this.callerPlugin.getGeneratedConfigPath('client'));
const clientSDKPath = yield this.createPackageByName('client-sdk', 'client-config');
const serverSDKPath = yield this.createPackageByName('server-sdk', 'server-config');
yield this.app.replaceTemplateValues((0, path_1.join)(clientSDKPath, 'src', 'index.ts'), '/*** UPDATE_ENV_BASED_ON_ENVIRONMENT ***/', `= ${JSON.stringify(yield this.filterEnvData(dotEnvPath, 'client'))}`);
yield this.app.replaceTemplateValues((0, path_1.join)(serverSDKPath, 'src', 'index.ts'), '// Add imports here', `import dotenv from 'dotenv'; \nimport findWorkspaceRoot from 'find-yarn-workspace-root'; \nimport { join } from 'path'; \n// Add imports here\n\nconst workspaceRoot: any = findWorkspaceRoot(__dirname); \ndotenv.config({\tpath: join(workspaceRoot, '.env')\n\t});\n`);
yield this.app.replaceTemplateValues((0, path_1.join)(serverSDKPath, 'src', 'index.ts'), '/*** UPDATE_ENV_BASED_ON_ENVIRONMENT ***/', `= process.env`);
yield this.app.replaceTemplateValues((0, path_1.join)(serverSDKPath, 'src', 'index.ts'), 'PROJECT_PATH_ENV', 'server-config');
this.getConfigInServiceSdk(clientSDKPath, 'client');
this.generateConfigInServiceSdk(clientSDKPath, serverSDKPath);
// Run prepare
// await this.prepare();
// await this.app.prepare();
// FIX: Do we need to prepare while building?
yield this.prepare();
});
}
prepare() {
return __awaiter(this, void 0, void 0, function* () {
//@ts-ignore
const packagePaths = this.callerPlugin.getGeneratedSDKPaths();
packagePaths.map((packagePath) => __awaiter(this, void 0, void 0, function* () {
(0, child_process_1.spawnSync)('sh', ['-c', `cd ${packagePath} && npm i && npm run build`], {
stdio: 'inherit',
});
}));
});
}
getConfigInServiceSdk(clientSDKPath, configType) {
const configPath = (0, path_1.join)(process.cwd(), 'config', `${configType}.ts`);
(0, fs_1.copyFileSync)(configPath, (0, path_1.join)(clientSDKPath, 'src', `${configType}.ts`));
}
generateConfigInServiceSdk(clientSDKPath, serverSDKPath) {
const developPlugin = this.app.getPluginByName('@gluestack-v2/glue-plugin-develop');
if (developPlugin) {
// @ts-ignore
const configPath = this.callerPlugin.getConfigPath();
const clientConfig = fs_1.default.readFileSync((0, path_1.join)(configPath, 'client.ts'), 'utf-8');
const serverConfig = fs_1.default.readFileSync((0, path_1.join)(configPath, 'server.ts'), 'utf-8');
const globalConfig = fs_1.default.readFileSync((0, path_1.join)(configPath, 'index.ts'), 'utf-8');
this.addConfigAlias(clientConfig, clientSDKPath);
this.addConfigAlias(serverConfig, serverSDKPath);
this.addConfigAlias(globalConfig, clientSDKPath);
this.addConfigAlias(globalConfig, serverSDKPath);
}
}
addConfigAlias(config, path) {
const regex = /{[\s\S]*providers\s*:\s*{\s*([\s\S]+)\s*},[\s\S]*}/;
const match = config.match(regex);
const singleLineCommentRegex = /\/\/.*(?:\r?\n|$)/g;
const stringWithoutSingleLineComments = config.replace(singleLineCommentRegex, '');
// Regular expression to remove multiline comments
const multiLineCommentRegex = /\/\*[\s\S]*?\*\//g;
const stringWithoutComments = stringWithoutSingleLineComments.replace(multiLineCommentRegex, '');
if (match && match[0]) {
// const configMap = JSON.parse(JSON.stringify(match[0]));
// const configKeys = this.extractProviderKeys(configMap);
const providers = this.getProvidersFromConfig(stringWithoutComments);
this.addProviderAliasInSdk(path, providers, stringWithoutComments);
// configKeys.map(async (provider: string) => {
// if (!(provider === 'providers')) {
// await this.addProviderAliasInSdk(provider, path, config);
// }
// });
}
}
addProviderAliasInSdk(packagePath, providers, config) {
Object.keys(providers).map((providerName) => __awaiter(this, void 0, void 0, function* () {
const getterTemplate = ` get ${providerName}(): ReturnType<${providers[providerName]}['getProvider']> | undefined {
return this.providers.get('${providerName}').getProvider();
}`;
this.updateTemplate((0, path_1.join)(packagePath, 'src', 'sdk.ts'), getterTemplate, '// **** Add getter functions after this comment ****', config);
}));
}
getProvidersFromConfig(config) {
// Regular expression to match the providers object content
const providersRegex = /providers:\s*{([\s\S]*?)},/;
// Find the providers content using regex
const match = config.match(providersRegex);
if (match) {
const providersContent = match[1];
// Function to parse providersContent into a JavaScript object
const parseProvidersObject = (str) => {
const keyValuePairsRegex = /\s*([\w$]+)\s*:\s*([\w$]+)\s*,?/g;
const providersObject = {};
let kvMatch;
while ((kvMatch = keyValuePairsRegex.exec(str))) {
const key = kvMatch[1];
const value = kvMatch[2];
// Check if the line is commented
const commentRegex = new RegExp(`\\s*//.*${key}\\s*:`);
if (commentRegex.test(str.substring(0, kvMatch.index))) {
continue; // Ignore commented lines
}
providersObject[key] = value;
}
return providersObject;
};
// Convert providersContent into a JavaScript object
const providersObject = parseProvidersObject(providersContent);
return providersObject;
}
else {
console.error('Providers object not found in the given string.');
}
}
extractImports(jsString) {
const importRegex = /import\s+([\w{},\s*]+)\s+from\s+['"](.+?)['"]/g;
// Array to store the matched imports
const imports = [];
let match;
while ((match = importRegex.exec(jsString)) !== null) {
const importedNames = match[1].split(',').map((name) => name.trim());
const fromModule = match[2];
imports.push({ importedNames, fromModule });
}
return imports;
}
extractProviderKeys(providerString) {
const regex = /\s*([\w$]+)\s*:/g;
const keys = [];
let match;
while ((match = regex.exec(providerString))) {
keys.push(match[1]);
}
return keys;
}
updateTemplate(filePath, replacementTemplate, sdkTemplateString, config) {
const data = fs_1.default.readFileSync(filePath, 'utf8');
const imports = this.extractImports(config);
let finalImports = ``;
imports.map((val) => {
if (!finalImports.includes(`import ${val.importedNames} from '${val.fromModule}';`) &&
!data.includes(`import ${val.importedNames} from '${val.fromModule}';`))
finalImports += `import ${val.importedNames} from '${val.fromModule}';\n`;
});
const commentIndex = data.indexOf(sdkTemplateString);
if (commentIndex === -1) {
console.error('Comment not found in the file.');
return;
}
if (data.includes(replacementTemplate)) {
return;
}
// Insert the string after the comment
const updatedContent = data.slice(0, commentIndex + sdkTemplateString.length) +
'\n' +
'\n' +
replacementTemplate +
data.slice(commentIndex + sdkTemplateString.length);
fs_1.default.writeFileSync(filePath, finalImports + updatedContent, 'utf8');
}
watch(callback) {
return __awaiter(this, void 0, void 0, function* () {
yield this.buildBeforeWatch();
// @ts-ignore
this.app.watch(
// @ts-ignore
this.callerPlugin.getConfigPath(), '', (events, path) => __awaiter(this, void 0, void 0, function* () {
if (events === 'change') {
this.build();
}
if (callback) {
callback(events, path);
}
}));
this.app.watch(dotEnvPath, '', (events, path) => __awaiter(this, void 0, void 0, function* () {
if (this) {
yield this.build();
}
if (callback) {
callback(events, path);
}
}));
});
}
}
exports.PluginInstance = PluginInstance;
});