@objectstack/runtime 9.11.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +54 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +54 -5
- package/dist/index.js.map +1 -1
- package/package.json +20 -19
package/dist/index.d.cts
CHANGED
|
@@ -117,6 +117,19 @@ interface StandaloneStackResult {
|
|
|
117
117
|
requires?: string[];
|
|
118
118
|
objects?: any[];
|
|
119
119
|
manifest?: any;
|
|
120
|
+
/**
|
|
121
|
+
* App-declared RBAC metadata, surfaced so the CLI (`serve`/`dev`/`start`)
|
|
122
|
+
* can wire it without a host `objectstack.config.ts`. In particular the
|
|
123
|
+
* `serve` command reads `permissions[]` to honour an app-declared default
|
|
124
|
+
* profile (ADR-0056 D7 — `appDefaultProfileName` → SecurityPlugin
|
|
125
|
+
* `fallbackPermissionSet`) and reads both `roles[]` and `permissions[]` to
|
|
126
|
+
* register application org roles with Better-Auth. Without these the
|
|
127
|
+
* artifact-serve path silently fell back to the built-in `member_default`
|
|
128
|
+
* (owner-only), so an `isDefault` profile declared purely in app metadata
|
|
129
|
+
* was ignored under `objectstack dev`.
|
|
130
|
+
*/
|
|
131
|
+
permissions?: any[];
|
|
132
|
+
roles?: any[];
|
|
120
133
|
}
|
|
121
134
|
declare function createStandaloneStack(config?: StandaloneStackConfig): Promise<StandaloneStackResult>;
|
|
122
135
|
|
package/dist/index.d.ts
CHANGED
|
@@ -117,6 +117,19 @@ interface StandaloneStackResult {
|
|
|
117
117
|
requires?: string[];
|
|
118
118
|
objects?: any[];
|
|
119
119
|
manifest?: any;
|
|
120
|
+
/**
|
|
121
|
+
* App-declared RBAC metadata, surfaced so the CLI (`serve`/`dev`/`start`)
|
|
122
|
+
* can wire it without a host `objectstack.config.ts`. In particular the
|
|
123
|
+
* `serve` command reads `permissions[]` to honour an app-declared default
|
|
124
|
+
* profile (ADR-0056 D7 — `appDefaultProfileName` → SecurityPlugin
|
|
125
|
+
* `fallbackPermissionSet`) and reads both `roles[]` and `permissions[]` to
|
|
126
|
+
* register application org roles with Better-Auth. Without these the
|
|
127
|
+
* artifact-serve path silently fell back to the built-in `member_default`
|
|
128
|
+
* (owner-only), so an `isDefault` profile declared purely in app metadata
|
|
129
|
+
* was ignored under `objectstack dev`.
|
|
130
|
+
*/
|
|
131
|
+
permissions?: any[];
|
|
132
|
+
roles?: any[];
|
|
120
133
|
}
|
|
121
134
|
declare function createStandaloneStack(config?: StandaloneStackConfig): Promise<StandaloneStackResult>;
|
|
122
135
|
|
package/dist/index.js
CHANGED
|
@@ -963,6 +963,35 @@ var init_app_plugin = __esm({
|
|
|
963
963
|
error: err?.message ?? String(err)
|
|
964
964
|
});
|
|
965
965
|
}
|
|
966
|
+
try {
|
|
967
|
+
const metadata = ctx.getService("metadata");
|
|
968
|
+
if (typeof metadata?.registerInMemory === "function") {
|
|
969
|
+
const securityBundle = this.bundle.manifest ? { ...this.bundle.manifest, ...this.bundle } : this.bundle;
|
|
970
|
+
const SECURITY_FIELDS = [
|
|
971
|
+
["roles", "role"],
|
|
972
|
+
["permissions", "permission"],
|
|
973
|
+
["sharingRules", "sharing_rule"],
|
|
974
|
+
["policies", "policy"]
|
|
975
|
+
];
|
|
976
|
+
let count = 0;
|
|
977
|
+
for (const [field, type] of SECURITY_FIELDS) {
|
|
978
|
+
const arr = securityBundle?.[field];
|
|
979
|
+
if (!Array.isArray(arr)) continue;
|
|
980
|
+
for (const item of arr) {
|
|
981
|
+
if (!item?.name) continue;
|
|
982
|
+
metadata.registerInMemory(type, item.name, item);
|
|
983
|
+
count += 1;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
if (count > 0) {
|
|
987
|
+
ctx.logger.info("Registered stack-declared security metadata", { appId, count });
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
} catch (err) {
|
|
991
|
+
ctx.logger.warn("[AppPlugin] failed to register security metadata", {
|
|
992
|
+
error: err?.message ?? String(err)
|
|
993
|
+
});
|
|
994
|
+
}
|
|
966
995
|
const stackBundle = this.bundle.default || this.bundle;
|
|
967
996
|
const runtime = stackBundle && typeof stackBundle.onEnable === "function" ? stackBundle : this.bundle;
|
|
968
997
|
if (runtime && typeof runtime.onEnable === "function") {
|
|
@@ -1587,6 +1616,8 @@ async function createStandaloneStack(config) {
|
|
|
1587
1616
|
const requires = Array.isArray(artifactBundle?.requires) ? artifactBundle.requires.filter((c) => typeof c === "string") : void 0;
|
|
1588
1617
|
const objects = Array.isArray(artifactBundle?.objects) ? artifactBundle.objects : void 0;
|
|
1589
1618
|
const manifest = artifactBundle?.manifest;
|
|
1619
|
+
const permissions = Array.isArray(artifactBundle?.permissions) ? artifactBundle.permissions : void 0;
|
|
1620
|
+
const roles = Array.isArray(artifactBundle?.roles) ? artifactBundle.roles : void 0;
|
|
1590
1621
|
return {
|
|
1591
1622
|
plugins,
|
|
1592
1623
|
api: {
|
|
@@ -1595,7 +1626,9 @@ async function createStandaloneStack(config) {
|
|
|
1595
1626
|
},
|
|
1596
1627
|
...requires ? { requires } : {},
|
|
1597
1628
|
...objects ? { objects } : {},
|
|
1598
|
-
...manifest ? { manifest } : {}
|
|
1629
|
+
...manifest ? { manifest } : {},
|
|
1630
|
+
...permissions ? { permissions } : {},
|
|
1631
|
+
...roles ? { roles } : {}
|
|
1599
1632
|
};
|
|
1600
1633
|
}
|
|
1601
1634
|
var StandaloneStackConfigSchema;
|
|
@@ -1997,25 +2030,33 @@ function coerceLocale(value) {
|
|
|
1997
2030
|
const s = typeof value === "string" ? value.trim() : value != null ? String(value).trim() : "";
|
|
1998
2031
|
return s || void 0;
|
|
1999
2032
|
}
|
|
2033
|
+
function coerceCurrency(value) {
|
|
2034
|
+
const s = typeof value === "string" ? value.trim().toUpperCase() : "";
|
|
2035
|
+
return /^[A-Z]{3}$/.test(s) ? s : void 0;
|
|
2036
|
+
}
|
|
2000
2037
|
async function resolveLocalization(opts, ql, sctx) {
|
|
2001
2038
|
try {
|
|
2002
2039
|
const settings = await opts.getService("settings");
|
|
2003
2040
|
if (settings && typeof settings.get === "function") {
|
|
2004
|
-
const [tzRes, localeRes] = await Promise.all([
|
|
2041
|
+
const [tzRes, localeRes, currencyRes] = await Promise.all([
|
|
2005
2042
|
settings.get("localization", "timezone", sctx).catch(() => void 0),
|
|
2006
|
-
settings.get("localization", "locale", sctx).catch(() => void 0)
|
|
2043
|
+
settings.get("localization", "locale", sctx).catch(() => void 0),
|
|
2044
|
+
settings.get("localization", "currency", sctx).catch(() => void 0)
|
|
2007
2045
|
]);
|
|
2008
2046
|
const tz = coerceTimeZone(tzRes?.value);
|
|
2009
2047
|
const locale = coerceLocale(localeRes?.value);
|
|
2010
|
-
|
|
2048
|
+
const currency = coerceCurrency(currencyRes?.value);
|
|
2049
|
+
if (tz || locale || currency) return { timezone: tz ?? "UTC", locale: locale ?? "en-US", currency };
|
|
2011
2050
|
}
|
|
2012
2051
|
} catch {
|
|
2013
2052
|
}
|
|
2014
2053
|
const tzRows = await tryFind(ql, "sys_setting", { namespace: "localization", key: "timezone", scope: "tenant" }, 1);
|
|
2015
2054
|
const localeRows = await tryFind(ql, "sys_setting", { namespace: "localization", key: "locale", scope: "tenant" }, 1);
|
|
2055
|
+
const currencyRows = await tryFind(ql, "sys_setting", { namespace: "localization", key: "currency", scope: "tenant" }, 1);
|
|
2016
2056
|
return {
|
|
2017
2057
|
timezone: coerceTimeZone(tzRows[0]?.value) ?? "UTC",
|
|
2018
|
-
locale: coerceLocale(localeRows[0]?.value) ?? "en-US"
|
|
2058
|
+
locale: coerceLocale(localeRows[0]?.value) ?? "en-US",
|
|
2059
|
+
currency: coerceCurrency(currencyRows[0]?.value)
|
|
2019
2060
|
};
|
|
2020
2061
|
}
|
|
2021
2062
|
async function resolveExecutionContext(opts) {
|
|
@@ -2070,6 +2111,13 @@ async function resolveExecutionContext(opts) {
|
|
|
2070
2111
|
}
|
|
2071
2112
|
}
|
|
2072
2113
|
}
|
|
2114
|
+
const userRoleRows = await tryFind(ql, "sys_user_role", { user_id: userId }, 200);
|
|
2115
|
+
for (const ur of userRoleRows) {
|
|
2116
|
+
const org = ur.organization_id ?? null;
|
|
2117
|
+
if (org && tenantId && org !== tenantId) continue;
|
|
2118
|
+
const r = ur.role;
|
|
2119
|
+
if (typeof r === "string" && r && !ctx.roles.includes(r)) ctx.roles.push(r);
|
|
2120
|
+
}
|
|
2073
2121
|
if (tenantId) {
|
|
2074
2122
|
const orgMembers = await tryFind(
|
|
2075
2123
|
ql,
|
|
@@ -2156,6 +2204,7 @@ async function resolveExecutionContext(opts) {
|
|
|
2156
2204
|
const localization = await resolveLocalization(opts, ql, { tenantId, userId });
|
|
2157
2205
|
ctx.timezone = localization.timezone;
|
|
2158
2206
|
ctx.locale = localization.locale;
|
|
2207
|
+
if (localization.currency) ctx.currency = localization.currency;
|
|
2159
2208
|
return ctx;
|
|
2160
2209
|
}
|
|
2161
2210
|
function isPermissionDeniedError(e) {
|