@ketvietlab/ketjs 0.1.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.
Files changed (283) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/dist/agent/capabilities.d.ts +62 -0
  4. package/dist/agent/capabilities.d.ts.map +1 -0
  5. package/dist/agent/capabilities.js +89 -0
  6. package/dist/agent/capabilities.js.map +1 -0
  7. package/dist/agent/permissions.d.ts +56 -0
  8. package/dist/agent/permissions.d.ts.map +1 -0
  9. package/dist/agent/permissions.js +209 -0
  10. package/dist/agent/permissions.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +698 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/codegen/dts.d.ts +3 -0
  16. package/dist/codegen/dts.d.ts.map +1 -0
  17. package/dist/codegen/dts.js +94 -0
  18. package/dist/codegen/dts.js.map +1 -0
  19. package/dist/data/adapter.d.ts +4 -0
  20. package/dist/data/adapter.d.ts.map +1 -0
  21. package/dist/data/adapter.js +18 -0
  22. package/dist/data/adapter.js.map +1 -0
  23. package/dist/data/changeset.d.ts +49 -0
  24. package/dist/data/changeset.d.ts.map +1 -0
  25. package/dist/data/changeset.js +206 -0
  26. package/dist/data/changeset.js.map +1 -0
  27. package/dist/data/expr.d.ts +59 -0
  28. package/dist/data/expr.d.ts.map +1 -0
  29. package/dist/data/expr.js +61 -0
  30. package/dist/data/expr.js.map +1 -0
  31. package/dist/data/fleet.d.ts +28 -0
  32. package/dist/data/fleet.d.ts.map +1 -0
  33. package/dist/data/fleet.js +82 -0
  34. package/dist/data/fleet.js.map +1 -0
  35. package/dist/data/list-search.d.ts +93 -0
  36. package/dist/data/list-search.d.ts.map +1 -0
  37. package/dist/data/list-search.js +268 -0
  38. package/dist/data/list-search.js.map +1 -0
  39. package/dist/data/migrate.d.ts +75 -0
  40. package/dist/data/migrate.d.ts.map +1 -0
  41. package/dist/data/migrate.js +136 -0
  42. package/dist/data/migrate.js.map +1 -0
  43. package/dist/data/pool.d.ts +20 -0
  44. package/dist/data/pool.d.ts.map +1 -0
  45. package/dist/data/pool.js +92 -0
  46. package/dist/data/pool.js.map +1 -0
  47. package/dist/data/query.d.ts +111 -0
  48. package/dist/data/query.d.ts.map +1 -0
  49. package/dist/data/query.js +268 -0
  50. package/dist/data/query.js.map +1 -0
  51. package/dist/data/sqlite.d.ts +3 -0
  52. package/dist/data/sqlite.d.ts.map +1 -0
  53. package/dist/data/sqlite.js +107 -0
  54. package/dist/data/sqlite.js.map +1 -0
  55. package/dist/data/time.d.ts +9 -0
  56. package/dist/data/time.d.ts.map +1 -0
  57. package/dist/data/time.js +107 -0
  58. package/dist/data/time.js.map +1 -0
  59. package/dist/index.d.ts +79 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +51 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/kernel/apps.d.ts +43 -0
  64. package/dist/kernel/apps.d.ts.map +1 -0
  65. package/dist/kernel/apps.js +234 -0
  66. package/dist/kernel/apps.js.map +1 -0
  67. package/dist/kernel/compose.d.ts +6 -0
  68. package/dist/kernel/compose.d.ts.map +1 -0
  69. package/dist/kernel/compose.js +976 -0
  70. package/dist/kernel/compose.js.map +1 -0
  71. package/dist/kernel/define.d.ts +9 -0
  72. package/dist/kernel/define.d.ts.map +1 -0
  73. package/dist/kernel/define.js +140 -0
  74. package/dist/kernel/define.js.map +1 -0
  75. package/dist/kernel/diff.d.ts +11 -0
  76. package/dist/kernel/diff.d.ts.map +1 -0
  77. package/dist/kernel/diff.js +106 -0
  78. package/dist/kernel/diff.js.map +1 -0
  79. package/dist/kernel/errors.d.ts +17 -0
  80. package/dist/kernel/errors.d.ts.map +1 -0
  81. package/dist/kernel/errors.js +43 -0
  82. package/dist/kernel/errors.js.map +1 -0
  83. package/dist/kernel/graph.d.ts +3 -0
  84. package/dist/kernel/graph.d.ts.map +1 -0
  85. package/dist/kernel/graph.js +56 -0
  86. package/dist/kernel/graph.js.map +1 -0
  87. package/dist/kernel/i18n.d.ts +43 -0
  88. package/dist/kernel/i18n.d.ts.map +1 -0
  89. package/dist/kernel/i18n.js +79 -0
  90. package/dist/kernel/i18n.js.map +1 -0
  91. package/dist/kernel/index.d.ts +7 -0
  92. package/dist/kernel/index.d.ts.map +1 -0
  93. package/dist/kernel/index.js +7 -0
  94. package/dist/kernel/index.js.map +1 -0
  95. package/dist/kernel/layout.d.ts +17 -0
  96. package/dist/kernel/layout.d.ts.map +1 -0
  97. package/dist/kernel/layout.js +77 -0
  98. package/dist/kernel/layout.js.map +1 -0
  99. package/dist/kernel/menu.d.ts +27 -0
  100. package/dist/kernel/menu.d.ts.map +1 -0
  101. package/dist/kernel/menu.js +65 -0
  102. package/dist/kernel/menu.js.map +1 -0
  103. package/dist/kernel/modules.d.ts +31 -0
  104. package/dist/kernel/modules.d.ts.map +1 -0
  105. package/dist/kernel/modules.js +322 -0
  106. package/dist/kernel/modules.js.map +1 -0
  107. package/dist/kernel/routes.d.ts +24 -0
  108. package/dist/kernel/routes.d.ts.map +1 -0
  109. package/dist/kernel/routes.js +98 -0
  110. package/dist/kernel/routes.js.map +1 -0
  111. package/dist/kernel/types.d.ts +8 -0
  112. package/dist/kernel/types.d.ts.map +1 -0
  113. package/dist/kernel/types.js +67 -0
  114. package/dist/kernel/types.js.map +1 -0
  115. package/dist/kernel/workspace.d.ts +62 -0
  116. package/dist/kernel/workspace.d.ts.map +1 -0
  117. package/dist/kernel/workspace.js +156 -0
  118. package/dist/kernel/workspace.js.map +1 -0
  119. package/dist/scaffold/index.d.ts +2 -0
  120. package/dist/scaffold/index.d.ts.map +1 -0
  121. package/dist/scaffold/index.js +49 -0
  122. package/dist/scaffold/index.js.map +1 -0
  123. package/dist/scaffold/templates/app.test.ts.tmpl +17 -0
  124. package/dist/scaffold/templates/biome.json.tmpl +30 -0
  125. package/dist/scaffold/templates/dev.mjs.tmpl +16 -0
  126. package/dist/scaffold/templates/gitignore.tmpl +24 -0
  127. package/dist/scaffold/templates/ket.workspace.ts.tmpl +18 -0
  128. package/dist/scaffold/templates/module.ts.tmpl +27 -0
  129. package/dist/scaffold/templates/package.json.tmpl +25 -0
  130. package/dist/scaffold/templates/tsconfig.json.tmpl +15 -0
  131. package/dist/server/boot.d.ts +173 -0
  132. package/dist/server/boot.d.ts.map +1 -0
  133. package/dist/server/boot.js +659 -0
  134. package/dist/server/boot.js.map +1 -0
  135. package/dist/server/config.d.ts +48 -0
  136. package/dist/server/config.d.ts.map +1 -0
  137. package/dist/server/config.js +82 -0
  138. package/dist/server/config.js.map +1 -0
  139. package/dist/server/ctx.d.ts +13 -0
  140. package/dist/server/ctx.d.ts.map +1 -0
  141. package/dist/server/ctx.js +496 -0
  142. package/dist/server/ctx.js.map +1 -0
  143. package/dist/server/fn.d.ts +34 -0
  144. package/dist/server/fn.d.ts.map +1 -0
  145. package/dist/server/fn.js +170 -0
  146. package/dist/server/fn.js.map +1 -0
  147. package/dist/server/http.d.ts +79 -0
  148. package/dist/server/http.d.ts.map +1 -0
  149. package/dist/server/http.js +459 -0
  150. package/dist/server/http.js.map +1 -0
  151. package/dist/server/idem.d.ts +31 -0
  152. package/dist/server/idem.d.ts.map +1 -0
  153. package/dist/server/idem.js +68 -0
  154. package/dist/server/idem.js.map +1 -0
  155. package/dist/server/jobs.d.ts +5 -0
  156. package/dist/server/jobs.d.ts.map +1 -0
  157. package/dist/server/jobs.js +24 -0
  158. package/dist/server/jobs.js.map +1 -0
  159. package/dist/server/multipart.d.ts +18 -0
  160. package/dist/server/multipart.d.ts.map +1 -0
  161. package/dist/server/multipart.js +183 -0
  162. package/dist/server/multipart.js.map +1 -0
  163. package/dist/server/project.d.ts +9 -0
  164. package/dist/server/project.d.ts.map +1 -0
  165. package/dist/server/project.js +67 -0
  166. package/dist/server/project.js.map +1 -0
  167. package/dist/server/queue.d.ts +80 -0
  168. package/dist/server/queue.d.ts.map +1 -0
  169. package/dist/server/queue.js +494 -0
  170. package/dist/server/queue.js.map +1 -0
  171. package/dist/server/respond.d.ts +91 -0
  172. package/dist/server/respond.d.ts.map +1 -0
  173. package/dist/server/respond.js +99 -0
  174. package/dist/server/respond.js.map +1 -0
  175. package/dist/server/runtime.d.ts +14 -0
  176. package/dist/server/runtime.d.ts.map +1 -0
  177. package/dist/server/runtime.js +25 -0
  178. package/dist/server/runtime.js.map +1 -0
  179. package/dist/server/session.d.ts +55 -0
  180. package/dist/server/session.d.ts.map +1 -0
  181. package/dist/server/session.js +172 -0
  182. package/dist/server/session.js.map +1 -0
  183. package/dist/server/sessionstore.d.ts +54 -0
  184. package/dist/server/sessionstore.d.ts.map +1 -0
  185. package/dist/server/sessionstore.js +232 -0
  186. package/dist/server/sessionstore.js.map +1 -0
  187. package/dist/server/storage/index.d.ts +11 -0
  188. package/dist/server/storage/index.d.ts.map +1 -0
  189. package/dist/server/storage/index.js +31 -0
  190. package/dist/server/storage/index.js.map +1 -0
  191. package/dist/server/storage/local.d.ts +5 -0
  192. package/dist/server/storage/local.d.ts.map +1 -0
  193. package/dist/server/storage/local.js +165 -0
  194. package/dist/server/storage/local.js.map +1 -0
  195. package/dist/server/storage/s3.d.ts +11 -0
  196. package/dist/server/storage/s3.d.ts.map +1 -0
  197. package/dist/server/storage/s3.js +133 -0
  198. package/dist/server/storage/s3.js.map +1 -0
  199. package/dist/server/storage/sigv4.d.ts +23 -0
  200. package/dist/server/storage/sigv4.d.ts.map +1 -0
  201. package/dist/server/storage/sigv4.js +79 -0
  202. package/dist/server/storage/sigv4.js.map +1 -0
  203. package/dist/server/storage/types.d.ts +37 -0
  204. package/dist/server/storage/types.d.ts.map +1 -0
  205. package/dist/server/storage/types.js +82 -0
  206. package/dist/server/storage/types.js.map +1 -0
  207. package/dist/server/stream.d.ts +43 -0
  208. package/dist/server/stream.d.ts.map +1 -0
  209. package/dist/server/stream.js +117 -0
  210. package/dist/server/stream.js.map +1 -0
  211. package/dist/server/streamstore.d.ts +29 -0
  212. package/dist/server/streamstore.d.ts.map +1 -0
  213. package/dist/server/streamstore.js +140 -0
  214. package/dist/server/streamstore.js.map +1 -0
  215. package/dist/server/tenants.d.ts +108 -0
  216. package/dist/server/tenants.d.ts.map +1 -0
  217. package/dist/server/tenants.js +172 -0
  218. package/dist/server/tenants.js.map +1 -0
  219. package/dist/server/transport/index.d.ts +5 -0
  220. package/dist/server/transport/index.d.ts.map +1 -0
  221. package/dist/server/transport/index.js +3 -0
  222. package/dist/server/transport/index.js.map +1 -0
  223. package/dist/server/transport/memory.d.ts +14 -0
  224. package/dist/server/transport/memory.d.ts.map +1 -0
  225. package/dist/server/transport/memory.js +36 -0
  226. package/dist/server/transport/memory.js.map +1 -0
  227. package/dist/server/transport/types.d.ts +44 -0
  228. package/dist/server/transport/types.d.ts.map +1 -0
  229. package/dist/server/transport/types.js +79 -0
  230. package/dist/server/transport/types.js.map +1 -0
  231. package/dist/server/worker.d.ts +33 -0
  232. package/dist/server/worker.d.ts.map +1 -0
  233. package/dist/server/worker.js +428 -0
  234. package/dist/server/worker.js.map +1 -0
  235. package/dist/testing.d.ts +146 -0
  236. package/dist/testing.d.ts.map +1 -0
  237. package/dist/testing.js +406 -0
  238. package/dist/testing.js.map +1 -0
  239. package/dist/theme/contracts.d.ts +4 -0
  240. package/dist/theme/contracts.d.ts.map +1 -0
  241. package/dist/theme/contracts.js +87 -0
  242. package/dist/theme/contracts.js.map +1 -0
  243. package/dist/theme/index.d.ts +8 -0
  244. package/dist/theme/index.d.ts.map +1 -0
  245. package/dist/theme/index.js +7 -0
  246. package/dist/theme/index.js.map +1 -0
  247. package/dist/theme/joints.d.ts +19 -0
  248. package/dist/theme/joints.d.ts.map +1 -0
  249. package/dist/theme/joints.js +126 -0
  250. package/dist/theme/joints.js.map +1 -0
  251. package/dist/theme/ktl/compile.d.ts +26 -0
  252. package/dist/theme/ktl/compile.d.ts.map +1 -0
  253. package/dist/theme/ktl/compile.js +226 -0
  254. package/dist/theme/ktl/compile.js.map +1 -0
  255. package/dist/theme/ktl/lexer.d.ts +20 -0
  256. package/dist/theme/ktl/lexer.d.ts.map +1 -0
  257. package/dist/theme/ktl/lexer.js +56 -0
  258. package/dist/theme/ktl/lexer.js.map +1 -0
  259. package/dist/theme/ktl/parser.d.ts +64 -0
  260. package/dist/theme/ktl/parser.d.ts.map +1 -0
  261. package/dist/theme/ktl/parser.js +220 -0
  262. package/dist/theme/ktl/parser.js.map +1 -0
  263. package/dist/theme/render.d.ts +19 -0
  264. package/dist/theme/render.d.ts.map +1 -0
  265. package/dist/theme/render.js +246 -0
  266. package/dist/theme/render.js.map +1 -0
  267. package/dist/theme/templates.d.ts +2 -0
  268. package/dist/theme/templates.d.ts.map +1 -0
  269. package/dist/theme/templates.js +40 -0
  270. package/dist/theme/templates.js.map +1 -0
  271. package/dist/theme/tokens.d.ts +4 -0
  272. package/dist/theme/tokens.d.ts.map +1 -0
  273. package/dist/theme/tokens.js +15 -0
  274. package/dist/theme/tokens.js.map +1 -0
  275. package/dist/theme/viewmodel.d.ts +6 -0
  276. package/dist/theme/viewmodel.d.ts.map +1 -0
  277. package/dist/theme/viewmodel.js +40 -0
  278. package/dist/theme/viewmodel.js.map +1 -0
  279. package/dist/types.d.ts +614 -0
  280. package/dist/types.d.ts.map +1 -0
  281. package/dist/types.js +3 -0
  282. package/dist/types.js.map +1 -0
  283. package/package.json +60 -0
@@ -0,0 +1,126 @@
1
+ // Rendering a joint inside a first-party screen.
2
+ //
3
+ // The screens are `html`` ` — typed, interactive, ours. What fills them is KTL —
4
+ // stringly-typed, sandboxed, a stranger's. That split is deliberate and it is the
5
+ // same one the storefront already makes: the code that runs is ours, the code that
6
+ // extends is theirs and cannot run.
7
+ //
8
+ // The alternative was a fill that is a function. It would have been typed, and it
9
+ // would have been arbitrary JavaScript from another module running in this process
10
+ // — which is the thing KTL exists to prevent. It would also have made `fills` the
11
+ // first part of the manifest that is not data: unprintable by `ket manifest`,
12
+ // undiffable by `ket diff`, unsnapshotable. A fill is text.
13
+ import { compileKtl } from './ktl/compile.js';
14
+ import { contractProps } from './contracts.js';
15
+ import { renderIsland, trustedMarkup } from '@ketvietlab/ketjs-view';
16
+ import { KetError } from '../kernel/errors.js';
17
+ export function createJoints(manifest, o = {}) {
18
+ // Compiled once. A fill is KTL source, so compiling per request would parse the
19
+ // same text on every page view.
20
+ const compiled = new Map();
21
+ const atRuntime = manifest.disabledModules !== undefined;
22
+ const stack = [];
23
+ const omitted = (key) => (manifest.joints[key]?.omittedBy.length ?? 0) > 0;
24
+ const renderJoint = (key, props) => {
25
+ const definition = manifest.joints[key];
26
+ if (!definition) {
27
+ throw new KetError({
28
+ code: 'E_UNKNOWN_JOINT',
29
+ message: `no installed module publishes joint "${key}"`,
30
+ hint: `published joints: ${Object.keys(manifest.joints).join(', ') || '(none)'}`,
31
+ });
32
+ }
33
+ if (omitted(key))
34
+ return '';
35
+ if (stack.includes(key)) {
36
+ throw new KetError({
37
+ code: 'E_JOINT_CYCLE',
38
+ message: `joint recursion: ${[...stack, key].join(' -> ')}`,
39
+ hint: 'a fill may render another joint, but never itself through any chain',
40
+ });
41
+ }
42
+ if (stack.length >= 16)
43
+ throw new KetError({ code: 'E_JOINT_TOO_DEEP', message: 'joint rendering exceeds 16 levels' });
44
+ stack.push(key);
45
+ try {
46
+ const scope = contractProps(manifest, 'joint', key, definition.props, props);
47
+ return (compiled.get(key) ?? []).map((entry) => entry.render(scope)).join('');
48
+ }
49
+ finally {
50
+ stack.pop();
51
+ }
52
+ };
53
+ const renderIslandAt = (name, scope) => {
54
+ const factory = o.islands?.[name];
55
+ const definition = manifest.islands[name];
56
+ if (!factory || !definition) {
57
+ if (atRuntime)
58
+ return '';
59
+ throw new KetError({
60
+ code: 'E_UNKNOWN_ISLAND',
61
+ message: `a fill places island "${name}", which no installed module provides`,
62
+ hint: `available islands: ${Object.keys(o.islands ?? {}).join(', ') || '(none)'}`,
63
+ });
64
+ }
65
+ return renderIsland(name, factory, contractProps(manifest, 'island', name, definition.props, scope), {
66
+ key: definition.key,
67
+ });
68
+ };
69
+ for (const fill of manifest.fills) {
70
+ const list = compiled.get(fill.joint) ?? [];
71
+ const entry = compileKtl(fill.template, {
72
+ name: `${fill.joint}#${list.length}`,
73
+ ...(o.translate ? { translate: o.translate } : {}),
74
+ renderJoint,
75
+ renderIsland: renderIslandAt,
76
+ });
77
+ const module = manifest.modules[fill.by];
78
+ for (const used of entry.jointsUsed) {
79
+ const target = manifest.joints[used];
80
+ if (!target)
81
+ throw new KetError({
82
+ code: 'E_FILL_UNKNOWN_JOINT',
83
+ module: fill.by,
84
+ message: `fill for "${fill.joint}" renders unknown joint "${used}"`,
85
+ });
86
+ if (target.owner !== fill.by && !module?.depends?.includes(target.owner))
87
+ throw new KetError({
88
+ code: 'E_FILL_NOT_DEPENDED',
89
+ module: fill.by,
90
+ message: `fill for "${fill.joint}" renders "${used}" without depending on "${target.owner}"`,
91
+ });
92
+ }
93
+ for (const used of entry.islandsUsed) {
94
+ const target = manifest.islands[used];
95
+ if (!target && !atRuntime)
96
+ throw new KetError({
97
+ code: 'E_FILL_UNKNOWN_ISLAND',
98
+ module: fill.by,
99
+ message: `fill for "${fill.joint}" places unknown island "${used}"`,
100
+ });
101
+ if (target && target.by !== fill.by && !module?.depends?.includes(target.by))
102
+ throw new KetError({
103
+ code: 'E_FILL_NOT_DEPENDED',
104
+ module: fill.by,
105
+ message: `fill for "${fill.joint}" places "${used}" without depending on "${target.by}"`,
106
+ });
107
+ }
108
+ list.push(entry);
109
+ compiled.set(fill.joint, list);
110
+ }
111
+ return {
112
+ shows: (key) => {
113
+ if (!manifest.joints[key]) {
114
+ throw new KetError({
115
+ code: 'E_UNKNOWN_JOINT',
116
+ message: `no installed module publishes joint "${key}"`,
117
+ });
118
+ }
119
+ return !omitted(key);
120
+ },
121
+ render(key, props = {}) {
122
+ return trustedMarkup(renderJoint(key, props));
123
+ },
124
+ };
125
+ }
126
+ //# sourceMappingURL=joints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joints.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/theme/joints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export type Filter = (value: unknown, arg?: unknown) => unknown;
2
+ export type Scope = Record<string, unknown>;
3
+ export type JointRenderer = (joint: string, scope: Scope) => string;
4
+ export type RegionRenderer = (name: string, scope: Scope) => string;
5
+ export type IslandRenderer = (name: string, scope: Scope) => string;
6
+ export type SectionsRenderer = (scope: Scope) => string;
7
+ export type CompileOpts = {
8
+ filters?: Record<string, Filter>;
9
+ /** Bound translator. A theme writes {{ 'website.page.title' | _ }}. */
10
+ translate?: (key: string, params?: Record<string, unknown>) => string;
11
+ renderJoint?: JointRenderer;
12
+ renderRegion?: RegionRenderer;
13
+ renderIsland?: IslandRenderer;
14
+ renderSections?: SectionsRenderer;
15
+ /** Renders another template by name, with the scope this one built for it. */
16
+ renderTemplate?: (name: string, scope: Scope, from: string) => string;
17
+ name?: string;
18
+ };
19
+ export type Compiled = {
20
+ render(scope: Scope): string;
21
+ jointsUsed: string[];
22
+ regionsUsed: string[];
23
+ islandsUsed: string[];
24
+ };
25
+ export declare function compileKtl(source: string, opts?: CompileOpts): Compiled;
26
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/theme/ktl/compile.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,KAAK,OAAO,CAAA;AAC/D,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAC3C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,CAAA;AACnE,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,CAAA;AACnE,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,CAAA;AACnE,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAA;AAEvD,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,uEAAuE;IACvE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IACrE,WAAW,CAAC,EAAE,aAAa,CAAA;IAC3B,YAAY,CAAC,EAAE,cAAc,CAAA;IAC7B,YAAY,CAAC,EAAE,cAAc,CAAA;IAC7B,cAAc,CAAC,EAAE,gBAAgB,CAAA;IACjC,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAA;IAC5B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAwGD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,QAAQ,CA4H3E"}
@@ -0,0 +1,226 @@
1
+ // Compile KTL to a tree of closures.
2
+ //
3
+ // There is no `new Function`, no `eval`, no string-to-code path anywhere here.
4
+ // A compiled template is a plain JavaScript function that can only read from the
5
+ // scope it is handed and call filters that were registered by name. That is the
6
+ // whole security argument for installing a stranger's theme.
7
+ import { parse } from './parser.js';
8
+ import { escapeHtml } from '@ketvietlab/ketjs-view';
9
+ import { KetError } from '../../kernel/errors.js';
10
+ // Intl formatters are expensive to construct and cheap to reuse. Building one per
11
+ // interpolation made the money filter cost more than the entire rest of the
12
+ // template engine put together — 4.5s against 38ms over the same 5000 renders.
13
+ const formatters = new Map();
14
+ const formatter = (locale, opts) => {
15
+ const key = locale + '|' + (opts.style ?? '') + (opts.currency ?? '');
16
+ let f = formatters.get(key);
17
+ if (!f) {
18
+ f = new Intl.NumberFormat(locale, opts);
19
+ formatters.set(key, f);
20
+ }
21
+ return f;
22
+ };
23
+ const BASE_FILTERS = {
24
+ upper: (v) => String(v ?? '').toUpperCase(),
25
+ lower: (v) => String(v ?? '').toLowerCase(),
26
+ money: (v, arg) => formatter(String(arg ?? 'vi-VN'), { style: 'currency', currency: 'VND' }).format(Number(v ?? 0) / 100),
27
+ number: (v) => formatter('vi-VN', {}).format(Number(v ?? 0)),
28
+ default: (v, arg) => (v == null || v === '' ? arg : v),
29
+ length: (v) => (Array.isArray(v) ? v.length : String(v ?? '').length),
30
+ truncate: (v, arg) => {
31
+ const n = Number(arg ?? 80);
32
+ const s = String(v ?? '');
33
+ return s.length > n ? s.slice(0, n) + '…' : s;
34
+ },
35
+ json: (v) => JSON.stringify(v),
36
+ };
37
+ // Reads one own-property at a time. A drop is a null-prototype object, so there is
38
+ // nothing above it to walk into even if a name slipped past the parser.
39
+ const hasOwn = Object.prototype.hasOwnProperty;
40
+ function readPath(scope, parts, where) {
41
+ // The scope chain bottoms out at a null-prototype object, so the first hop needs
42
+ // no own-property guard: "constructor" and friends resolve to undefined anyway.
43
+ let cur = scope[parts[0]];
44
+ for (let i = 1; i < parts.length; i++) {
45
+ if (cur == null || typeof cur !== 'object')
46
+ return undefined;
47
+ const p = parts[i];
48
+ if (!hasOwn.call(cur, p))
49
+ return undefined;
50
+ cur = cur[p];
51
+ }
52
+ if (typeof cur === 'function') {
53
+ throw new KetError({
54
+ code: 'E_KTL_CALLABLE',
55
+ message: `${where} reached a function via "${parts.join('.')}"`,
56
+ hint: 'view models must expose data only',
57
+ });
58
+ }
59
+ return cur;
60
+ }
61
+ function compileExpr(e, o) {
62
+ if (e.k === 'lit') {
63
+ const v = e.value;
64
+ return () => v;
65
+ }
66
+ if (e.k === 'path') {
67
+ const parts = e.parts, where = at(o);
68
+ return (s) => readPath(s, parts, where);
69
+ }
70
+ if (e.k === 'not') {
71
+ const inner = compileExpr(e.src, o);
72
+ return (s) => !inner(s);
73
+ }
74
+ if (e.k === 'cmp') {
75
+ const l = compileExpr(e.left, o), r = compileExpr(e.right, o), op = e.op;
76
+ return (s) => {
77
+ const a = l(s), b = r(s);
78
+ if (op === '==')
79
+ return a === b;
80
+ if (op === '!=')
81
+ return a !== b;
82
+ if (op === '>')
83
+ return a > b;
84
+ if (op === '<')
85
+ return a < b;
86
+ if (op === '>=')
87
+ return a >= b;
88
+ return a <= b;
89
+ };
90
+ }
91
+ const src = compileExpr(e.src, o);
92
+ const arg = e.arg ? compileExpr(e.arg, o) : null;
93
+ const fn = o.filters[e.name];
94
+ if (!fn) {
95
+ throw new KetError({
96
+ code: 'E_KTL_UNKNOWN_FILTER',
97
+ message: `${at(o)} uses unknown filter "${e.name}"`,
98
+ hint: `registered filters: ${Object.keys(o.filters).sort().join(', ')}`,
99
+ });
100
+ }
101
+ return (s) => fn(src(s), arg ? arg(s) : undefined);
102
+ }
103
+ /** Where an error is: the template name doubles as its file name, plus the line. */
104
+ const at = (o) => `template "${o.name}"` + (o.line ? ` line ${o.line}` : '');
105
+ export function compileKtl(source, opts = {}) {
106
+ const name = opts.name ?? '(anonymous)';
107
+ // Translation arrives as a filter rather than a function in scope, because scope
108
+ // holds data only — a theme that could call functions would be a theme that could
109
+ // run code, which is the whole thing KTL exists to prevent.
110
+ //
111
+ // The filter is named _ , the way gettext and Odoo name it: it appears often
112
+ // enough in markup that a longer name would cost more than it explains.
113
+ const filters = {
114
+ ...BASE_FILTERS,
115
+ ...(opts.translate
116
+ ? {
117
+ _: (v, arg) => opts.translate(String(v), arg),
118
+ }
119
+ : {}),
120
+ ...(opts.filters ?? {}),
121
+ };
122
+ const jointsUsed = [];
123
+ const regionsUsed = [];
124
+ const islandsUsed = [];
125
+ const compileNodes = (nodes) => nodes.map((n) => {
126
+ if (n.k === 'text') {
127
+ const v = n.value;
128
+ return (_s, out) => {
129
+ out.push(v);
130
+ };
131
+ }
132
+ if (n.k === 'out') {
133
+ const t = compileExpr(n.expr, { filters, name, line: n.line });
134
+ const raw = n.raw;
135
+ return (s, out) => {
136
+ const v = t(s);
137
+ out.push(v == null ? '' : raw ? String(v) : escapeHtml(v));
138
+ };
139
+ }
140
+ if (n.k === 'if') {
141
+ const cond = compileExpr(n.cond, { filters, name, line: n.line });
142
+ const a = compileNodes(n.then), b = compileNodes(n.else);
143
+ return (s, out) => {
144
+ for (const f of cond(s) ? a : b)
145
+ f(s, out);
146
+ };
147
+ }
148
+ if (n.k === 'for') {
149
+ const src = compileExpr(n.src, { filters, name, line: n.line });
150
+ const body = compileNodes(n.body);
151
+ const varName = n.name;
152
+ return (s, out) => {
153
+ const list = src(s);
154
+ if (!Array.isArray(list))
155
+ return;
156
+ const n = list.length;
157
+ // One child scope for the whole loop rather than one per item. The body
158
+ // runs synchronously and never retains it, so reuse is safe.
159
+ const inner = Object.create(s);
160
+ const loop = { index: 0, first: true, last: n === 1, length: n };
161
+ inner['loop'] = loop;
162
+ for (let i = 0; i < n; i++) {
163
+ inner[varName] = list[i];
164
+ loop.index = i;
165
+ loop.first = i === 0;
166
+ loop.last = i === n - 1;
167
+ for (const f of body)
168
+ f(inner, out);
169
+ }
170
+ };
171
+ }
172
+ if (n.k === 'joint') {
173
+ jointsUsed.push(n.joint);
174
+ const key = n.joint;
175
+ return (s, out) => {
176
+ out.push(opts.renderJoint ? opts.renderJoint(key, s) : '');
177
+ };
178
+ }
179
+ if (n.k === 'sections') {
180
+ return (s, out) => {
181
+ out.push(opts.renderSections ? opts.renderSections(s) : '');
182
+ };
183
+ }
184
+ if (n.k === 'render') {
185
+ const target = n.template;
186
+ const args = Object.entries(n.args).map(([k, e]) => [k, compileExpr(e, { filters, name, line: n.line })]);
187
+ const where = at({ name, line: n.line });
188
+ return (s, out) => {
189
+ // A null-prototype object with only what was passed. Not Object.create(s):
190
+ // the callee must not be able to read the caller by accident, or on purpose.
191
+ const inner = Object.create(null);
192
+ for (const [k, thunk] of args)
193
+ inner[k] = thunk(s);
194
+ out.push(opts.renderTemplate ? opts.renderTemplate(target, inner, where) : '');
195
+ };
196
+ }
197
+ if (n.k === 'island') {
198
+ islandsUsed.push(n.name);
199
+ const iname = n.name;
200
+ return (s, out) => {
201
+ out.push(opts.renderIsland ? opts.renderIsland(iname, s) : '');
202
+ };
203
+ }
204
+ regionsUsed.push(n.name);
205
+ const rname = n.name;
206
+ return (s, out) => {
207
+ out.push(opts.renderRegion ? opts.renderRegion(rname, s) : '');
208
+ };
209
+ });
210
+ const program = compileNodes(parse(source));
211
+ return {
212
+ jointsUsed,
213
+ regionsUsed,
214
+ islandsUsed,
215
+ render(scope) {
216
+ const out = [];
217
+ // sealScope() already hands over a null-prototype object; copying it again
218
+ // on every render was pure waste.
219
+ const safe = Object.getPrototypeOf(scope) === null ? scope : Object.assign(Object.create(null), scope);
220
+ for (const f of program)
221
+ f(safe, out);
222
+ return out.join('');
223
+ },
224
+ };
225
+ }
226
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../../../../../packages/ketjs/src/theme/ktl/compile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export type Token = {
2
+ type: 'text';
3
+ value: string;
4
+ line: number;
5
+ } | {
6
+ type: 'expr';
7
+ value: string;
8
+ line: number;
9
+ } | {
10
+ type: 'tag';
11
+ value: string;
12
+ line: number;
13
+ };
14
+ export declare function lex(src: string): Token[];
15
+ export declare class KtlSyntaxError extends Error {
16
+ code: string;
17
+ line: number;
18
+ constructor(message: string, line: number);
19
+ }
20
+ //# sourceMappingURL=lexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/theme/ktl/lexer.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,KAAK,GACb;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhD,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,EAAE,CAsCxC;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,IAAI,SAAiB;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAGxC;CACF"}
@@ -0,0 +1,56 @@
1
+ // KTL — Ket Template Language.
2
+ //
3
+ // Themes are third-party code installed into somebody else's app, so a theme must
4
+ // not be able to run arbitrary JavaScript: no fetch, no env, no database. That is
5
+ // why this is a separate language rather than a tagged template literal, and why
6
+ // it compiles to a tree of closures instead of through `new Function`.
7
+ export function lex(src) {
8
+ const out = [];
9
+ let i = 0;
10
+ let line = 1;
11
+ const countLines = (s) => {
12
+ for (const ch of s)
13
+ if (ch === '\n')
14
+ line++;
15
+ };
16
+ while (i < src.length) {
17
+ const openExpr = src.indexOf('{{', i);
18
+ const openTag = src.indexOf('{%', i);
19
+ const openNote = src.indexOf('{#', i);
20
+ const next = [openExpr, openTag, openNote].filter((n) => n !== -1).sort((a, b) => a - b)[0] ?? -1;
21
+ if (next === -1) {
22
+ const value = src.slice(i);
23
+ if (value)
24
+ out.push({ type: 'text', value, line });
25
+ break;
26
+ }
27
+ if (next > i) {
28
+ const value = src.slice(i, next);
29
+ out.push({ type: 'text', value, line });
30
+ countLines(value);
31
+ }
32
+ // A comment is lexed and dropped rather than left to the text branch, so it
33
+ // never reaches the output. Templates are files now; a language a theme author
34
+ // cannot annotate is a language they will annotate wrongly, in the markup.
35
+ const open = src.slice(next, next + 2);
36
+ const closer = open === '{{' ? '}}' : open === '{%' ? '%}' : '#}';
37
+ const close = src.indexOf(closer, next + 2);
38
+ if (close === -1)
39
+ throw new KtlSyntaxError(`unterminated ${open} at line ${line}`, line);
40
+ const raw = src.slice(next + 2, close).trim();
41
+ if (open !== '{#')
42
+ out.push({ type: open === '{{' ? 'expr' : 'tag', value: raw, line });
43
+ countLines(src.slice(next, close));
44
+ i = close + closer.length;
45
+ }
46
+ return out;
47
+ }
48
+ export class KtlSyntaxError extends Error {
49
+ code = 'E_KTL_SYNTAX';
50
+ line;
51
+ constructor(message, line) {
52
+ super(message);
53
+ this.line = line;
54
+ }
55
+ }
56
+ //# sourceMappingURL=lexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../../../../../../packages/ketjs/src/theme/ktl/lexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ export type Expr = {
2
+ k: 'path';
3
+ parts: string[];
4
+ } | {
5
+ k: 'lit';
6
+ value: string | number | boolean;
7
+ } | {
8
+ k: 'filter';
9
+ src: Expr;
10
+ name: string;
11
+ arg: Expr | null;
12
+ } | {
13
+ k: 'cmp';
14
+ op: string;
15
+ left: Expr;
16
+ right: Expr;
17
+ } | {
18
+ k: 'not';
19
+ src: Expr;
20
+ };
21
+ export type Node = {
22
+ k: 'text';
23
+ value: string;
24
+ } | {
25
+ k: 'out';
26
+ expr: Expr;
27
+ raw: boolean;
28
+ line: number;
29
+ } | {
30
+ k: 'if';
31
+ cond: Expr;
32
+ then: Node[];
33
+ else: Node[];
34
+ line: number;
35
+ } | {
36
+ k: 'for';
37
+ name: string;
38
+ src: Expr;
39
+ body: Node[];
40
+ line: number;
41
+ } | {
42
+ k: 'render';
43
+ template: string;
44
+ args: Record<string, Expr>;
45
+ line: number;
46
+ } | {
47
+ k: 'joint';
48
+ joint: string;
49
+ line: number;
50
+ } | {
51
+ k: 'region';
52
+ name: string;
53
+ line: number;
54
+ } | {
55
+ k: 'island';
56
+ name: string;
57
+ line: number;
58
+ } | {
59
+ k: 'sections';
60
+ line: number;
61
+ };
62
+ export declare function parseExpr(src: string, line: number): Expr;
63
+ export declare function parse(src: string): Node[];
64
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/theme/ktl/parser.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,IAAI,GACZ;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAC9B;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;CAAE,GAC9C;IAAE,CAAC,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,GAC1D;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GACjD;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,CAAA;AAE3B,MAAM,MAAM,IAAI,GACZ;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,CAAC,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,CAAC,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,CAAC,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,CAAC,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,CAAC,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,CAAC,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAOnC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAsCzD;AAmDD,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,CAqHzC"}