@arcote.tech/arc 0.4.10 → 0.5.1
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/context-element/aggregate/aggregate-data.d.ts +12 -32
- package/dist/context-element/aggregate/aggregate-element.d.ts +58 -31
- package/dist/context-element/command/command-context.d.ts +7 -25
- package/dist/context-element/command/command-data.d.ts +4 -13
- package/dist/context-element/command/command.d.ts +11 -121
- package/dist/context-element/command/index.d.ts +1 -1
- package/dist/context-element/element-context.d.ts +25 -15
- package/dist/context-element/function/arc-function-data.d.ts +70 -0
- package/dist/context-element/function/arc-function.d.ts +119 -0
- package/dist/context-element/function/index.d.ts +3 -0
- package/dist/context-element/index.d.ts +1 -0
- package/dist/context-element/listener/listener.d.ts +12 -93
- package/dist/context-element/route/route.d.ts +7 -68
- package/dist/elements/object.d.ts +4 -4
- package/dist/index.js +291 -216
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/merge-unsafe.d.ts +6 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1697,6 +1697,165 @@ function event(name, payload) {
|
|
|
1697
1697
|
});
|
|
1698
1698
|
}
|
|
1699
1699
|
|
|
1700
|
+
// src/context-element/element-context.ts
|
|
1701
|
+
function buildElementContext(queryElements, mutationElements, adapters) {
|
|
1702
|
+
const queryMap = new Map;
|
|
1703
|
+
const mutateMap = new Map;
|
|
1704
|
+
const queryProps = {};
|
|
1705
|
+
for (const element of queryElements) {
|
|
1706
|
+
if (element.queryContext) {
|
|
1707
|
+
const ctx = element.queryContext(adapters);
|
|
1708
|
+
queryProps[element.name] = ctx;
|
|
1709
|
+
queryMap.set(element, ctx);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
const mutateProps = {};
|
|
1713
|
+
for (const element of mutationElements) {
|
|
1714
|
+
if (element.mutateContext) {
|
|
1715
|
+
const ctx = element.mutateContext(adapters);
|
|
1716
|
+
mutateProps[element.name] = ctx;
|
|
1717
|
+
mutateMap.set(element, ctx);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
const queryFn = (element) => {
|
|
1721
|
+
const cached = queryMap.get(element);
|
|
1722
|
+
if (cached)
|
|
1723
|
+
return cached;
|
|
1724
|
+
if (element.queryContext) {
|
|
1725
|
+
const ctx = element.queryContext(adapters);
|
|
1726
|
+
queryMap.set(element, ctx);
|
|
1727
|
+
return ctx;
|
|
1728
|
+
}
|
|
1729
|
+
throw new Error(`Element "${element.name}" has no queryContext`);
|
|
1730
|
+
};
|
|
1731
|
+
Object.assign(queryFn, queryProps);
|
|
1732
|
+
const mutateFn = (element) => {
|
|
1733
|
+
const cached = mutateMap.get(element);
|
|
1734
|
+
if (cached)
|
|
1735
|
+
return cached;
|
|
1736
|
+
if (element.mutateContext) {
|
|
1737
|
+
const ctx = element.mutateContext(adapters);
|
|
1738
|
+
mutateMap.set(element, ctx);
|
|
1739
|
+
return ctx;
|
|
1740
|
+
}
|
|
1741
|
+
throw new Error(`Element "${element.name}" has no mutateContext`);
|
|
1742
|
+
};
|
|
1743
|
+
Object.assign(mutateFn, mutateProps);
|
|
1744
|
+
return {
|
|
1745
|
+
query: queryFn,
|
|
1746
|
+
mutate: mutateFn
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
// src/context-element/function/arc-function.ts
|
|
1751
|
+
class ArcFunction {
|
|
1752
|
+
data;
|
|
1753
|
+
constructor(data) {
|
|
1754
|
+
this.data = data;
|
|
1755
|
+
}
|
|
1756
|
+
withParams(schema) {
|
|
1757
|
+
return new ArcFunction({
|
|
1758
|
+
...this.data,
|
|
1759
|
+
params: schema instanceof ArcObject ? schema : new ArcObject(schema)
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
withResult(schema) {
|
|
1763
|
+
return new ArcFunction({
|
|
1764
|
+
...this.data,
|
|
1765
|
+
result: schema instanceof ArcObject ? schema : new ArcObject(schema)
|
|
1766
|
+
});
|
|
1767
|
+
}
|
|
1768
|
+
query(elements) {
|
|
1769
|
+
return new ArcFunction({
|
|
1770
|
+
...this.data,
|
|
1771
|
+
queryElements: elements
|
|
1772
|
+
});
|
|
1773
|
+
}
|
|
1774
|
+
mutate(elements) {
|
|
1775
|
+
return new ArcFunction({
|
|
1776
|
+
...this.data,
|
|
1777
|
+
mutationElements: elements
|
|
1778
|
+
});
|
|
1779
|
+
}
|
|
1780
|
+
protectedBy(token, check) {
|
|
1781
|
+
const existingProtections = this.data.protections || [];
|
|
1782
|
+
return new ArcFunction({
|
|
1783
|
+
...this.data,
|
|
1784
|
+
protections: [...existingProtections, { token, check }]
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
description(desc) {
|
|
1788
|
+
return new ArcFunction({
|
|
1789
|
+
...this.data,
|
|
1790
|
+
description: desc
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
handle(handler) {
|
|
1794
|
+
return new ArcFunction({
|
|
1795
|
+
...this.data,
|
|
1796
|
+
handler
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
get isPublic() {
|
|
1800
|
+
return !this.hasProtections;
|
|
1801
|
+
}
|
|
1802
|
+
get hasProtections() {
|
|
1803
|
+
return (this.data.protections?.length ?? 0) > 0;
|
|
1804
|
+
}
|
|
1805
|
+
get protections() {
|
|
1806
|
+
return this.data.protections || [];
|
|
1807
|
+
}
|
|
1808
|
+
get handler() {
|
|
1809
|
+
return this.data.handler;
|
|
1810
|
+
}
|
|
1811
|
+
get params() {
|
|
1812
|
+
return this.data.params;
|
|
1813
|
+
}
|
|
1814
|
+
get result() {
|
|
1815
|
+
return this.data.result;
|
|
1816
|
+
}
|
|
1817
|
+
async verifyProtections(tokens) {
|
|
1818
|
+
if (!this.data.protections || this.data.protections.length === 0) {
|
|
1819
|
+
return true;
|
|
1820
|
+
}
|
|
1821
|
+
for (const protection of this.data.protections) {
|
|
1822
|
+
const tokenInstance = tokens.find((t) => t.getTokenDefinition() === protection.token);
|
|
1823
|
+
if (!tokenInstance) {
|
|
1824
|
+
return false;
|
|
1825
|
+
}
|
|
1826
|
+
const result = await protection.check(tokenInstance);
|
|
1827
|
+
if (result === false) {
|
|
1828
|
+
return false;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
return true;
|
|
1832
|
+
}
|
|
1833
|
+
buildContext(adapters) {
|
|
1834
|
+
return buildElementContext(this.data.queryElements || [], this.data.mutationElements || [], adapters);
|
|
1835
|
+
}
|
|
1836
|
+
toJsonSchema() {
|
|
1837
|
+
return {
|
|
1838
|
+
params: this.data.params?.toJsonSchema?.() ?? null,
|
|
1839
|
+
result: this.data.result?.toJsonSchema?.() ?? null
|
|
1840
|
+
};
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
var defaultFunctionData = {
|
|
1844
|
+
params: null,
|
|
1845
|
+
result: null,
|
|
1846
|
+
queryElements: [],
|
|
1847
|
+
mutationElements: [],
|
|
1848
|
+
protections: [],
|
|
1849
|
+
handler: null,
|
|
1850
|
+
description: undefined
|
|
1851
|
+
};
|
|
1852
|
+
function arcFunction() {
|
|
1853
|
+
return new ArcFunction(defaultFunctionData);
|
|
1854
|
+
}
|
|
1855
|
+
function arcFunctionWithCtx() {
|
|
1856
|
+
return new ArcFunction(defaultFunctionData);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1700
1859
|
// src/context-element/aggregate/aggregate-base.ts
|
|
1701
1860
|
class AggregateBase {
|
|
1702
1861
|
value;
|
|
@@ -1797,12 +1956,13 @@ class ArcAggregateElement extends ArcContextElement {
|
|
|
1797
1956
|
};
|
|
1798
1957
|
return new ArcAggregateElement(this.name, this._id_factory, this.schema, [...this._events, entry], this._protections, this._mutateMethods, this._queryMethods, this._seeds);
|
|
1799
1958
|
}
|
|
1800
|
-
mutateMethod(methodName,
|
|
1801
|
-
const
|
|
1959
|
+
mutateMethod(methodName, configure) {
|
|
1960
|
+
const baseFn = arcFunctionWithCtx();
|
|
1961
|
+
const configuredFn = configure(baseFn);
|
|
1802
1962
|
const entry = {
|
|
1803
1963
|
name: methodName,
|
|
1804
|
-
params:
|
|
1805
|
-
handler
|
|
1964
|
+
params: configuredFn.data.params,
|
|
1965
|
+
handler: configuredFn.data.handler
|
|
1806
1966
|
};
|
|
1807
1967
|
return new ArcAggregateElement(this.name, this._id_factory, this.schema, this._events, this._protections, [...this._mutateMethods, entry], this._queryMethods, this._seeds);
|
|
1808
1968
|
}
|
|
@@ -1811,13 +1971,18 @@ class ArcAggregateElement extends ArcContextElement {
|
|
|
1811
1971
|
throw new Error("cron() must be called immediately after mutateMethod()");
|
|
1812
1972
|
}
|
|
1813
1973
|
const methods = [...this._mutateMethods];
|
|
1814
|
-
methods[methods.length - 1] = {
|
|
1974
|
+
methods[methods.length - 1] = {
|
|
1975
|
+
...methods[methods.length - 1],
|
|
1976
|
+
cronExpression: expression
|
|
1977
|
+
};
|
|
1815
1978
|
return new ArcAggregateElement(this.name, this._id_factory, this.schema, this._events, this._protections, methods, this._queryMethods, this._seeds);
|
|
1816
1979
|
}
|
|
1817
|
-
clientQuery(methodName,
|
|
1980
|
+
clientQuery(methodName, configure) {
|
|
1981
|
+
const baseFn = arcFunctionWithCtx();
|
|
1982
|
+
const configuredFn = configure(baseFn);
|
|
1818
1983
|
const entry = {
|
|
1819
1984
|
name: methodName,
|
|
1820
|
-
handler
|
|
1985
|
+
handler: configuredFn.data.handler
|
|
1821
1986
|
};
|
|
1822
1987
|
return new ArcAggregateElement(this.name, this._id_factory, this.schema, this._events, this._protections, this._mutateMethods, [...this._queryMethods, entry], this._seeds);
|
|
1823
1988
|
}
|
|
@@ -1862,16 +2027,21 @@ class ArcAggregateElement extends ArcContextElement {
|
|
|
1862
2027
|
static __aggregateCronMethods = cronMethods;
|
|
1863
2028
|
static getEvent(eventName) {
|
|
1864
2029
|
const entry = events.find((e) => e.isPublic && e.event.name === eventName);
|
|
1865
|
-
|
|
2030
|
+
if (!entry)
|
|
2031
|
+
return;
|
|
2032
|
+
return Object.assign(Object.create(Object.getPrototypeOf(entry.event)), entry.event, { name: `${name}.${entry.event.name}` });
|
|
1866
2033
|
}
|
|
1867
2034
|
};
|
|
1868
|
-
Object.defineProperty(AggregateClass, "name", {
|
|
2035
|
+
Object.defineProperty(AggregateClass, "name", {
|
|
2036
|
+
value: `${name}Aggregate`
|
|
2037
|
+
});
|
|
1869
2038
|
return AggregateClass;
|
|
1870
2039
|
}
|
|
1871
2040
|
getHandlers() {
|
|
1872
2041
|
const handlers = {};
|
|
1873
2042
|
for (const entry of this._events) {
|
|
1874
|
-
|
|
2043
|
+
const key = entry.isInline ? `${this.name}.${entry.event.name}` : entry.event.name;
|
|
2044
|
+
handlers[key] = entry.handler;
|
|
1875
2045
|
}
|
|
1876
2046
|
return handlers;
|
|
1877
2047
|
}
|
|
@@ -1880,7 +2050,9 @@ class ArcAggregateElement extends ArcContextElement {
|
|
|
1880
2050
|
}
|
|
1881
2051
|
getEvent(eventName) {
|
|
1882
2052
|
const entry = this._events.find((e) => e.isPublic && e.event.name === eventName);
|
|
1883
|
-
|
|
2053
|
+
if (!entry)
|
|
2054
|
+
return;
|
|
2055
|
+
return Object.assign(Object.create(Object.getPrototypeOf(entry.event)), entry.event, { name: `${this.name}.${entry.event.name}` });
|
|
1884
2056
|
}
|
|
1885
2057
|
get cronMethods() {
|
|
1886
2058
|
const result = [];
|
|
@@ -1901,9 +2073,16 @@ class ArcAggregateElement extends ArcContextElement {
|
|
|
1901
2073
|
const AggCtor = this.Aggregate;
|
|
1902
2074
|
const result = {};
|
|
1903
2075
|
for (const method of this._queryMethods) {
|
|
2076
|
+
if (!method.handler)
|
|
2077
|
+
continue;
|
|
2078
|
+
const handler = method.handler;
|
|
1904
2079
|
result[method.name] = (...args) => {
|
|
1905
|
-
const ctx = {
|
|
1906
|
-
|
|
2080
|
+
const ctx = {
|
|
2081
|
+
$query: privateQuery,
|
|
2082
|
+
$auth: auth,
|
|
2083
|
+
Aggregate: AggCtor
|
|
2084
|
+
};
|
|
2085
|
+
return handler(ctx, ...args);
|
|
1907
2086
|
};
|
|
1908
2087
|
}
|
|
1909
2088
|
return result;
|
|
@@ -2020,13 +2199,15 @@ class ArcAggregateElement extends ArcContextElement {
|
|
|
2020
2199
|
const ctx = {};
|
|
2021
2200
|
for (const entry of events) {
|
|
2022
2201
|
const arcEvent = entry.event;
|
|
2202
|
+
if (!entry.isInline)
|
|
2203
|
+
continue;
|
|
2023
2204
|
ctx[arcEvent.name] = {
|
|
2024
2205
|
emit: async (payload) => {
|
|
2025
2206
|
if (!adapters.eventPublisher) {
|
|
2026
2207
|
throw new Error(`Cannot emit event "${arcEvent.name}": no eventPublisher adapter available`);
|
|
2027
2208
|
}
|
|
2028
2209
|
const eventInstance = {
|
|
2029
|
-
type: arcEvent.name
|
|
2210
|
+
type: `${aggregateName}.${arcEvent.name}`,
|
|
2030
2211
|
payload,
|
|
2031
2212
|
id: `${Date.now()}_${Math.random().toString(36).slice(2)}`,
|
|
2032
2213
|
createdAt: new Date
|
|
@@ -2046,7 +2227,10 @@ class ArcAggregateElement extends ArcContextElement {
|
|
|
2046
2227
|
if (!adapters.commandWire) {
|
|
2047
2228
|
throw new Error(`Method "${method.name}" is server-only but no commandWire (WebSocket) is available.`);
|
|
2048
2229
|
}
|
|
2049
|
-
const wireAuth = adapters.scope ? {
|
|
2230
|
+
const wireAuth = adapters.scope ? {
|
|
2231
|
+
scope: adapters.scope.scopeName,
|
|
2232
|
+
token: adapters.scope.getToken()
|
|
2233
|
+
} : undefined;
|
|
2050
2234
|
return adapters.commandWire.executeCommand(`${aggregateName}.${method.name}`, params, wireAuth);
|
|
2051
2235
|
}
|
|
2052
2236
|
const ctx = buildMutateMethodCtx();
|
|
@@ -2078,129 +2262,71 @@ function aggregate(name, id2, schema) {
|
|
|
2078
2262
|
const schemaObj = schema instanceof ArcObject ? schema : new ArcObject(schema);
|
|
2079
2263
|
return new ArcAggregateElement(name, id2, schemaObj);
|
|
2080
2264
|
}
|
|
2081
|
-
// src/context-element/element-context.ts
|
|
2082
|
-
function buildElementContext(queryElements, mutationElements, adapters) {
|
|
2083
|
-
const context2 = {};
|
|
2084
|
-
const elementMap = new Map;
|
|
2085
|
-
for (const element of queryElements) {
|
|
2086
|
-
if (element.queryContext) {
|
|
2087
|
-
const ctx = element.queryContext(adapters);
|
|
2088
|
-
context2[element.name] = ctx;
|
|
2089
|
-
elementMap.set(element, ctx);
|
|
2090
|
-
}
|
|
2091
|
-
}
|
|
2092
|
-
for (const element of mutationElements) {
|
|
2093
|
-
if (element.mutateContext) {
|
|
2094
|
-
const ctx = element.mutateContext(adapters);
|
|
2095
|
-
context2[element.name] = ctx;
|
|
2096
|
-
elementMap.set(element, ctx);
|
|
2097
|
-
}
|
|
2098
|
-
}
|
|
2099
|
-
context2.get = (element) => {
|
|
2100
|
-
const cached = elementMap.get(element);
|
|
2101
|
-
if (cached)
|
|
2102
|
-
return cached;
|
|
2103
|
-
if (element.queryContext) {
|
|
2104
|
-
const ctx = element.queryContext(adapters);
|
|
2105
|
-
elementMap.set(element, ctx);
|
|
2106
|
-
return ctx;
|
|
2107
|
-
}
|
|
2108
|
-
if (element.mutateContext) {
|
|
2109
|
-
const ctx = element.mutateContext(adapters);
|
|
2110
|
-
elementMap.set(element, ctx);
|
|
2111
|
-
return ctx;
|
|
2112
|
-
}
|
|
2113
|
-
throw new Error(`Element "${element.name}" has no context available`);
|
|
2114
|
-
};
|
|
2115
|
-
context2.query = (element) => {
|
|
2116
|
-
if (!element.queryContext) {
|
|
2117
|
-
throw new Error(`Element "${element.name}" has no queryContext`);
|
|
2118
|
-
}
|
|
2119
|
-
return element.queryContext(adapters);
|
|
2120
|
-
};
|
|
2121
|
-
context2.mutate = (element) => {
|
|
2122
|
-
if (!element.mutateContext) {
|
|
2123
|
-
throw new Error(`Element "${element.name}" has no mutateContext`);
|
|
2124
|
-
}
|
|
2125
|
-
return element.mutateContext(adapters);
|
|
2126
|
-
};
|
|
2127
|
-
return context2;
|
|
2128
|
-
}
|
|
2129
|
-
|
|
2130
2265
|
// src/context-element/command/command.ts
|
|
2131
2266
|
class ArcCommand extends ArcContextElement {
|
|
2132
2267
|
data;
|
|
2133
|
-
|
|
2268
|
+
#fn;
|
|
2269
|
+
constructor(data, fn) {
|
|
2134
2270
|
super(data.name);
|
|
2135
2271
|
this.data = data;
|
|
2272
|
+
this.#fn = fn ?? new ArcFunction({
|
|
2273
|
+
params: data.params,
|
|
2274
|
+
result: null,
|
|
2275
|
+
queryElements: data.queryElements,
|
|
2276
|
+
mutationElements: data.mutationElements,
|
|
2277
|
+
protections: data.protections || [],
|
|
2278
|
+
handler: data.handler ?? null,
|
|
2279
|
+
description: data.description
|
|
2280
|
+
});
|
|
2136
2281
|
}
|
|
2137
2282
|
description(description) {
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
description
|
|
2141
|
-
});
|
|
2283
|
+
const newFn = this.#fn.description(description);
|
|
2284
|
+
return new ArcCommand({ ...this.data, description }, newFn);
|
|
2142
2285
|
}
|
|
2143
2286
|
get isPublic() {
|
|
2144
|
-
return
|
|
2287
|
+
return this.#fn.isPublic;
|
|
2145
2288
|
}
|
|
2146
2289
|
query(elements) {
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
queryElements: elements
|
|
2150
|
-
});
|
|
2290
|
+
const newFn = this.#fn.query(elements);
|
|
2291
|
+
return new ArcCommand({ ...this.data, queryElements: elements }, newFn);
|
|
2151
2292
|
}
|
|
2152
2293
|
mutate(elements) {
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
mutationElements: elements
|
|
2156
|
-
});
|
|
2294
|
+
const newFn = this.#fn.mutate(elements);
|
|
2295
|
+
return new ArcCommand({ ...this.data, mutationElements: elements }, newFn);
|
|
2157
2296
|
}
|
|
2158
2297
|
withParams(schema) {
|
|
2298
|
+
const newFn = this.#fn.withParams(schema);
|
|
2159
2299
|
return new ArcCommand({
|
|
2160
2300
|
...this.data,
|
|
2161
2301
|
params: schema instanceof ArcObject ? schema : new ArcObject(schema)
|
|
2162
|
-
});
|
|
2302
|
+
}, newFn);
|
|
2163
2303
|
}
|
|
2164
2304
|
withResult(...schemas) {
|
|
2165
|
-
return new ArcCommand({
|
|
2166
|
-
...this.data,
|
|
2167
|
-
results: schemas
|
|
2168
|
-
});
|
|
2305
|
+
return new ArcCommand({ ...this.data, results: schemas }, this.#fn);
|
|
2169
2306
|
}
|
|
2170
2307
|
handle(handler) {
|
|
2171
|
-
|
|
2172
|
-
...this.data,
|
|
2308
|
+
const newFn = new ArcFunction({
|
|
2309
|
+
...this.#fn.data,
|
|
2173
2310
|
handler
|
|
2174
2311
|
});
|
|
2312
|
+
return new ArcCommand({ ...this.data, handler }, newFn);
|
|
2175
2313
|
}
|
|
2176
2314
|
protectBy(token, check) {
|
|
2315
|
+
const newFn = this.#fn.protectedBy(token, check);
|
|
2177
2316
|
const existingProtections = this.data.protections || [];
|
|
2178
2317
|
return new ArcCommand({
|
|
2179
2318
|
...this.data,
|
|
2180
2319
|
protections: [...existingProtections, { token, check }]
|
|
2181
|
-
});
|
|
2320
|
+
}, newFn);
|
|
2182
2321
|
}
|
|
2183
2322
|
get hasProtections() {
|
|
2184
|
-
return
|
|
2323
|
+
return this.#fn.hasProtections;
|
|
2185
2324
|
}
|
|
2186
2325
|
get protections() {
|
|
2187
|
-
return this.
|
|
2326
|
+
return this.#fn.protections;
|
|
2188
2327
|
}
|
|
2189
2328
|
async verifyProtections(tokens) {
|
|
2190
|
-
|
|
2191
|
-
return true;
|
|
2192
|
-
}
|
|
2193
|
-
for (const protection of this.data.protections) {
|
|
2194
|
-
const tokenInstance = tokens.find((t) => t.getTokenDefinition() === protection.token);
|
|
2195
|
-
if (!tokenInstance) {
|
|
2196
|
-
return false;
|
|
2197
|
-
}
|
|
2198
|
-
const allowed = await protection.check(tokenInstance);
|
|
2199
|
-
if (!allowed) {
|
|
2200
|
-
return false;
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
return true;
|
|
2329
|
+
return this.#fn.verifyProtections(tokens);
|
|
2204
2330
|
}
|
|
2205
2331
|
async init(environment, adapters) {
|
|
2206
2332
|
if (environment === "server" && this.data.handler && adapters.commandWire?.registerCommandHandler) {
|
|
@@ -2227,12 +2353,11 @@ class ArcCommand extends ArcContextElement {
|
|
|
2227
2353
|
throw new Error(`Command "${this.data.name}" has no handler`);
|
|
2228
2354
|
}
|
|
2229
2355
|
const context2 = this.buildCommandContext(adapters);
|
|
2230
|
-
|
|
2231
|
-
return result;
|
|
2356
|
+
return await this.data.handler(context2, params);
|
|
2232
2357
|
}
|
|
2233
2358
|
buildCommandContext(adapters) {
|
|
2234
|
-
const context2 =
|
|
2235
|
-
if (this.hasProtections && adapters.authAdapter) {
|
|
2359
|
+
const context2 = this.#fn.buildContext(adapters);
|
|
2360
|
+
if (this.#fn.hasProtections && adapters.authAdapter) {
|
|
2236
2361
|
const decoded = adapters.authAdapter.getDecoded();
|
|
2237
2362
|
if (decoded) {
|
|
2238
2363
|
context2.$auth = {
|
|
@@ -2272,46 +2397,41 @@ function command(name) {
|
|
|
2272
2397
|
// src/context-element/listener/listener.ts
|
|
2273
2398
|
class ArcListener extends ArcContextElement {
|
|
2274
2399
|
data;
|
|
2400
|
+
#fn;
|
|
2275
2401
|
unsubscribers = [];
|
|
2276
|
-
constructor(data) {
|
|
2402
|
+
constructor(data, fn) {
|
|
2277
2403
|
super(data.name);
|
|
2278
2404
|
this.data = data;
|
|
2405
|
+
this.#fn = fn ?? new ArcFunction({
|
|
2406
|
+
params: null,
|
|
2407
|
+
result: null,
|
|
2408
|
+
queryElements: data.queryElements,
|
|
2409
|
+
mutationElements: data.mutationElements,
|
|
2410
|
+
protections: [],
|
|
2411
|
+
handler: null,
|
|
2412
|
+
description: data.description
|
|
2413
|
+
});
|
|
2279
2414
|
}
|
|
2280
2415
|
description(description) {
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
description
|
|
2284
|
-
});
|
|
2416
|
+
const newFn = this.#fn.description(description);
|
|
2417
|
+
return new ArcListener({ ...this.data, description }, newFn);
|
|
2285
2418
|
}
|
|
2286
2419
|
listenTo(events) {
|
|
2287
|
-
return new ArcListener({
|
|
2288
|
-
...this.data,
|
|
2289
|
-
eventElements: events
|
|
2290
|
-
});
|
|
2420
|
+
return new ArcListener({ ...this.data, eventElements: events }, this.#fn);
|
|
2291
2421
|
}
|
|
2292
2422
|
query(elements) {
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
queryElements: elements
|
|
2296
|
-
});
|
|
2423
|
+
const newFn = this.#fn.query(elements);
|
|
2424
|
+
return new ArcListener({ ...this.data, queryElements: elements }, newFn);
|
|
2297
2425
|
}
|
|
2298
2426
|
mutate(elements) {
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
mutationElements: elements
|
|
2302
|
-
});
|
|
2427
|
+
const newFn = this.#fn.mutate(elements);
|
|
2428
|
+
return new ArcListener({ ...this.data, mutationElements: elements }, newFn);
|
|
2303
2429
|
}
|
|
2304
2430
|
async() {
|
|
2305
|
-
return new ArcListener({
|
|
2306
|
-
...this.data,
|
|
2307
|
-
isAsync: true
|
|
2308
|
-
});
|
|
2431
|
+
return new ArcListener({ ...this.data, isAsync: true }, this.#fn);
|
|
2309
2432
|
}
|
|
2310
2433
|
handle(handler) {
|
|
2311
|
-
return new ArcListener({
|
|
2312
|
-
...this.data,
|
|
2313
|
-
handler
|
|
2314
|
-
});
|
|
2434
|
+
return new ArcListener({ ...this.data, handler }, this.#fn);
|
|
2315
2435
|
}
|
|
2316
2436
|
get eventElements() {
|
|
2317
2437
|
return this.data.eventElements || [];
|
|
@@ -2341,48 +2461,7 @@ class ArcListener extends ArcContextElement {
|
|
|
2341
2461
|
async handleEvent(event2, adapters) {
|
|
2342
2462
|
if (!this.data.handler)
|
|
2343
2463
|
return;
|
|
2344
|
-
const context2 = this.
|
|
2345
|
-
if (this.data.isAsync) {
|
|
2346
|
-
Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
2347
|
-
console.error(`Async listener "${this.data.name}" error:`, error);
|
|
2348
|
-
});
|
|
2349
|
-
} else {
|
|
2350
|
-
await this.data.handler(context2, event2);
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
buildListenerContext(adapters) {
|
|
2354
|
-
const context2 = {};
|
|
2355
|
-
const elementMap = new Map;
|
|
2356
|
-
for (const element of this.data.queryElements) {
|
|
2357
|
-
if (element.queryContext) {
|
|
2358
|
-
const elementContext = element.queryContext(adapters);
|
|
2359
|
-
context2[element.name] = elementContext;
|
|
2360
|
-
elementMap.set(element, elementContext);
|
|
2361
|
-
}
|
|
2362
|
-
}
|
|
2363
|
-
for (const element of this.data.mutationElements) {
|
|
2364
|
-
if (element.mutateContext) {
|
|
2365
|
-
const elementContext = element.mutateContext(adapters);
|
|
2366
|
-
context2[element.name] = elementContext;
|
|
2367
|
-
elementMap.set(element, elementContext);
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
context2.get = (element) => {
|
|
2371
|
-
const cached = elementMap.get(element);
|
|
2372
|
-
if (cached)
|
|
2373
|
-
return cached;
|
|
2374
|
-
if (element.queryContext) {
|
|
2375
|
-
const ctx = element.queryContext(adapters);
|
|
2376
|
-
elementMap.set(element, ctx);
|
|
2377
|
-
return ctx;
|
|
2378
|
-
}
|
|
2379
|
-
if (element.mutateContext) {
|
|
2380
|
-
const ctx = element.mutateContext(adapters);
|
|
2381
|
-
elementMap.set(element, ctx);
|
|
2382
|
-
return ctx;
|
|
2383
|
-
}
|
|
2384
|
-
throw new Error(`Element "${element.name}" has no context available`);
|
|
2385
|
-
};
|
|
2464
|
+
const context2 = this.#fn.buildContext(adapters);
|
|
2386
2465
|
if (adapters.authAdapter) {
|
|
2387
2466
|
const decoded = adapters.authAdapter.getDecoded();
|
|
2388
2467
|
if (decoded) {
|
|
@@ -2392,7 +2471,13 @@ class ArcListener extends ArcContextElement {
|
|
|
2392
2471
|
};
|
|
2393
2472
|
}
|
|
2394
2473
|
}
|
|
2395
|
-
|
|
2474
|
+
if (this.data.isAsync) {
|
|
2475
|
+
Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
2476
|
+
console.error(`Async listener "${this.data.name}" error:`, error);
|
|
2477
|
+
});
|
|
2478
|
+
} else {
|
|
2479
|
+
await this.data.handler(context2, event2);
|
|
2480
|
+
}
|
|
2396
2481
|
}
|
|
2397
2482
|
destroy() {
|
|
2398
2483
|
for (const unsubscribe of this.unsubscribers) {
|
|
@@ -2413,52 +2498,48 @@ function listener(name) {
|
|
|
2413
2498
|
// src/context-element/route/route.ts
|
|
2414
2499
|
class ArcRoute extends ArcContextElement {
|
|
2415
2500
|
data;
|
|
2416
|
-
|
|
2501
|
+
#fn;
|
|
2502
|
+
constructor(data, fn) {
|
|
2417
2503
|
super(data.name);
|
|
2418
2504
|
this.data = data;
|
|
2505
|
+
this.#fn = fn ?? new ArcFunction({
|
|
2506
|
+
params: null,
|
|
2507
|
+
result: null,
|
|
2508
|
+
queryElements: data.queryElements,
|
|
2509
|
+
mutationElements: data.mutationElements,
|
|
2510
|
+
protections: data.protections || [],
|
|
2511
|
+
handler: null,
|
|
2512
|
+
description: data.description
|
|
2513
|
+
});
|
|
2419
2514
|
}
|
|
2420
2515
|
description(description) {
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
description
|
|
2424
|
-
});
|
|
2516
|
+
const newFn = this.#fn.description(description);
|
|
2517
|
+
return new ArcRoute({ ...this.data, description }, newFn);
|
|
2425
2518
|
}
|
|
2426
2519
|
path(path) {
|
|
2427
|
-
return new ArcRoute({
|
|
2428
|
-
...this.data,
|
|
2429
|
-
path
|
|
2430
|
-
});
|
|
2520
|
+
return new ArcRoute({ ...this.data, path }, this.#fn);
|
|
2431
2521
|
}
|
|
2432
2522
|
public() {
|
|
2433
|
-
return new ArcRoute({
|
|
2434
|
-
...this.data,
|
|
2435
|
-
isPublic: true
|
|
2436
|
-
});
|
|
2523
|
+
return new ArcRoute({ ...this.data, isPublic: true }, this.#fn);
|
|
2437
2524
|
}
|
|
2438
2525
|
query(elements) {
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
queryElements: elements
|
|
2442
|
-
});
|
|
2526
|
+
const newFn = this.#fn.query(elements);
|
|
2527
|
+
return new ArcRoute({ ...this.data, queryElements: elements }, newFn);
|
|
2443
2528
|
}
|
|
2444
2529
|
mutate(elements) {
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
mutationElements: elements
|
|
2448
|
-
});
|
|
2530
|
+
const newFn = this.#fn.mutate(elements);
|
|
2531
|
+
return new ArcRoute({ ...this.data, mutationElements: elements }, newFn);
|
|
2449
2532
|
}
|
|
2450
2533
|
protectBy(token, check) {
|
|
2534
|
+
const newFn = this.#fn.protectedBy(token, check);
|
|
2451
2535
|
const existingProtections = this.data.protections || [];
|
|
2452
2536
|
return new ArcRoute({
|
|
2453
2537
|
...this.data,
|
|
2454
2538
|
protections: [...existingProtections, { token, check }]
|
|
2455
|
-
});
|
|
2539
|
+
}, newFn);
|
|
2456
2540
|
}
|
|
2457
2541
|
handle(handlers) {
|
|
2458
|
-
return new ArcRoute({
|
|
2459
|
-
...this.data,
|
|
2460
|
-
handlers
|
|
2461
|
-
});
|
|
2542
|
+
return new ArcRoute({ ...this.data, handlers }, this.#fn);
|
|
2462
2543
|
}
|
|
2463
2544
|
get routePath() {
|
|
2464
2545
|
return this.data.path || `/${this.data.name}`;
|
|
@@ -2470,7 +2551,7 @@ class ArcRoute extends ArcContextElement {
|
|
|
2470
2551
|
return this.data.isPublic;
|
|
2471
2552
|
}
|
|
2472
2553
|
get hasProtections() {
|
|
2473
|
-
return
|
|
2554
|
+
return this.#fn.hasProtections;
|
|
2474
2555
|
}
|
|
2475
2556
|
get protections() {
|
|
2476
2557
|
return this.data.protections || [];
|
|
@@ -2502,23 +2583,10 @@ class ArcRoute extends ArcContextElement {
|
|
|
2502
2583
|
if (this.data.isPublic) {
|
|
2503
2584
|
return true;
|
|
2504
2585
|
}
|
|
2505
|
-
|
|
2506
|
-
return true;
|
|
2507
|
-
}
|
|
2508
|
-
for (const protection of this.data.protections) {
|
|
2509
|
-
const tokenInstance = tokens.find((t) => t.getTokenDefinition() === protection.token);
|
|
2510
|
-
if (!tokenInstance) {
|
|
2511
|
-
return false;
|
|
2512
|
-
}
|
|
2513
|
-
const allowed = await protection.check(tokenInstance);
|
|
2514
|
-
if (!allowed) {
|
|
2515
|
-
return false;
|
|
2516
|
-
}
|
|
2517
|
-
}
|
|
2518
|
-
return true;
|
|
2586
|
+
return this.#fn.verifyProtections(tokens);
|
|
2519
2587
|
}
|
|
2520
2588
|
buildContext(adapters, authParams) {
|
|
2521
|
-
const context2 =
|
|
2589
|
+
const context2 = this.#fn.buildContext(adapters);
|
|
2522
2590
|
if (authParams) {
|
|
2523
2591
|
context2.$auth = authParams;
|
|
2524
2592
|
}
|
|
@@ -2972,6 +3040,8 @@ function deepMerge(target, source) {
|
|
|
2972
3040
|
function isPlainObject(item) {
|
|
2973
3041
|
return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
|
|
2974
3042
|
}
|
|
3043
|
+
// src/utils/merge-unsafe.ts
|
|
3044
|
+
var mergeUnsafe = (schema, unsafeSchema) => Object.assign({}, schema, unsafeSchema);
|
|
2975
3045
|
// src/utils/murmur-hash.ts
|
|
2976
3046
|
function murmurHash(key, seed = 0) {
|
|
2977
3047
|
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
@@ -5010,12 +5080,14 @@ export {
|
|
|
5010
5080
|
number,
|
|
5011
5081
|
mutationExecutor,
|
|
5012
5082
|
murmurHash,
|
|
5083
|
+
mergeUnsafe,
|
|
5013
5084
|
listener,
|
|
5014
5085
|
id,
|
|
5015
5086
|
file,
|
|
5016
5087
|
extractDatabaseAgnosticSchema,
|
|
5017
5088
|
executeDescriptor,
|
|
5018
5089
|
event,
|
|
5090
|
+
defaultFunctionData,
|
|
5019
5091
|
deepMerge,
|
|
5020
5092
|
date,
|
|
5021
5093
|
customId,
|
|
@@ -5028,6 +5100,8 @@ export {
|
|
|
5028
5100
|
boolean,
|
|
5029
5101
|
blob,
|
|
5030
5102
|
array,
|
|
5103
|
+
arcFunctionWithCtx,
|
|
5104
|
+
arcFunction,
|
|
5031
5105
|
applyOrderByAndLimit,
|
|
5032
5106
|
any,
|
|
5033
5107
|
aggregate,
|
|
@@ -5066,6 +5140,7 @@ export {
|
|
|
5066
5140
|
ArcNumber,
|
|
5067
5141
|
ArcListener,
|
|
5068
5142
|
ArcId,
|
|
5143
|
+
ArcFunction,
|
|
5069
5144
|
ArcFragmentBase,
|
|
5070
5145
|
ArcFile,
|
|
5071
5146
|
ArcEvent,
|