locutus
Version:
Locutus other languages' standard libraries to JavaScript for fun and educational purposes
160 lines (159 loc) • 5.69 kB
JavaScript
import { isPhpAssocObject, isPhpCallable, } from "./_phpTypes.js";
const isIniBag = (value) => isPhpAssocObject(value);
const isLocaleBag = (value) => isPhpAssocObject(value);
const isLocaleCategoryBag = (value) => isPhpAssocObject(value);
const globalContext = typeof window === 'object' && window !== null ? window : typeof global === 'object' && global !== null ? global : {};
const ensurePhpRuntimeObject = () => {
let locutus = globalContext.$locutus;
if (typeof locutus !== 'object' || locutus === null) {
locutus = {};
globalContext.$locutus = locutus;
}
let php = locutus.php;
if (typeof php !== 'object' || php === null) {
php = {};
locutus.php = php;
}
return php;
};
export function ensurePhpRuntimeState() {
const php = ensurePhpRuntimeObject();
const iniValue = php.ini;
const localesValue = php.locales;
const localeCategoriesValue = php.localeCategories;
const pointersValue = php.pointers;
const ini = isIniBag(iniValue) ? iniValue : {};
const locales = isLocaleBag(localesValue) ? localesValue : {};
const localeCategories = isLocaleCategoryBag(localeCategoriesValue) ? localeCategoriesValue : {};
const pointers = Array.isArray(pointersValue) ? pointersValue : [];
if (iniValue !== ini) {
php.ini = ini;
}
if (localesValue !== locales) {
php.locales = locales;
}
if (localeCategoriesValue !== localeCategories) {
php.localeCategories = localeCategories;
}
if (pointersValue !== pointers) {
php.pointers = pointers;
}
const localeDefaultValue = php.locale_default;
const localeDefault = typeof localeDefaultValue === 'string' ? localeDefaultValue : undefined;
return {
ini,
locales,
localeCategories,
pointers,
locale_default: localeDefault,
};
}
export function setPhpLocaleDefault(localeDefault) {
const php = ensurePhpRuntimeObject();
php.locale_default = localeDefault;
}
export function getPhpRuntimeEntry(key) {
const php = ensurePhpRuntimeObject();
const value = php[key];
return typeof value === 'undefined' ? undefined : value;
}
export function setPhpRuntimeEntry(key, value) {
const php = ensurePhpRuntimeObject();
php[key] = value;
}
export function getPhpRuntimeNumber(key, fallback) {
const value = getPhpRuntimeEntry(key);
return typeof value === 'number' ? value : fallback;
}
export function getPhpRuntimeBoolean(key, fallback) {
const value = getPhpRuntimeEntry(key);
return typeof value === 'boolean' ? value : fallback;
}
export function getPhpRuntimeString(key, fallback) {
const value = getPhpRuntimeEntry(key);
return typeof value === 'string' ? value : fallback;
}
export function getPhpGlobalEntry(key) {
const value = globalContext[key];
return typeof value === 'undefined' ? undefined : value;
}
export function setPhpGlobalEntry(key, value) {
globalContext[key] = value;
}
export function getPhpGlobalScope() {
return globalContext;
}
export function getPhpGlobalCallable(key) {
const value = getPhpGlobalEntry(key);
return isPhpCallable(value) ? value : undefined;
}
export function getPhpObjectEntry(value, key) {
if ((typeof value !== 'object' && typeof value !== 'function') || value === null) {
return undefined;
}
let current = value;
while (current) {
const descriptor = Object.getOwnPropertyDescriptor(current, key);
if (descriptor) {
if (typeof descriptor.get === 'function') {
const getterValue = descriptor.get.call(value);
return typeof getterValue === 'undefined' ? undefined : getterValue;
}
const directValue = descriptor.value;
return typeof directValue === 'undefined' ? undefined : directValue;
}
current = Object.getPrototypeOf(current);
}
return undefined;
}
export function setPhpObjectEntry(value, key, entry) {
if ((typeof value !== 'object' && typeof value !== 'function') || value === null) {
return false;
}
const container = value;
let current = container;
while (current) {
const descriptor = Object.getOwnPropertyDescriptor(current, key);
if (descriptor) {
if (typeof descriptor.set === 'function') {
descriptor.set.call(container, entry);
return true;
}
if (descriptor.writable) {
Object.defineProperty(container, key, {
configurable: descriptor.configurable ?? true,
enumerable: descriptor.enumerable ?? true,
value: entry,
writable: true,
});
return true;
}
return false;
}
current = Object.getPrototypeOf(current);
}
Object.defineProperty(container, key, {
configurable: true,
enumerable: true,
value: entry,
writable: true,
});
return true;
}
function getPhpLocaleEntry(category) {
const runtime = ensurePhpRuntimeState();
const localeName = runtime.localeCategories[category];
if (typeof localeName !== 'string') {
return undefined;
}
const localeEntry = runtime.locales[localeName];
return isPhpAssocObject(localeEntry) ? localeEntry : undefined;
}
export function getPhpLocaleGroup(category, groupKey) {
const localeEntry = getPhpLocaleEntry(category);
if (!localeEntry) {
return undefined;
}
const group = localeEntry[groupKey];
return isPhpAssocObject(group) ? group : undefined;
}