irgen 0.2.0 → 0.2.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/CHANGELOG.md +13 -0
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -1
- package/dist/dsl/aggregator.d.ts +0 -1
- package/dist/dsl/aggregator.js +0 -1
- package/dist/dsl/frontend-runtime.d.ts +0 -1
- package/dist/dsl/frontend-runtime.js +31 -30
- package/dist/dsl/runtime.d.ts +0 -1
- package/dist/dsl/runtime.js +16 -15
- package/dist/emit/backend/adapters.d.ts +0 -1
- package/dist/emit/backend/adapters.js +0 -1
- package/dist/emit/backend/backend-tsmorph.d.ts +0 -1
- package/dist/emit/backend/backend-tsmorph.js +0 -1
- package/dist/emit/backend/fake-backend.d.ts +0 -1
- package/dist/emit/backend/fake-backend.js +0 -1
- package/dist/emit/backend/packaging.d.ts +0 -1
- package/dist/emit/backend/packaging.js +0 -1
- package/dist/emit/backend/server.d.ts +0 -1
- package/dist/emit/backend/server.js +0 -1
- package/dist/emit/cli/cli-fake.d.ts +0 -1
- package/dist/emit/cli/cli-fake.js +0 -1
- package/dist/emit/electron/electron-shell.d.ts +0 -1
- package/dist/emit/electron/electron-shell.js +0 -1
- package/dist/emit/engine.d.ts +0 -1
- package/dist/emit/engine.js +0 -1
- package/dist/emit/format.d.ts +0 -1
- package/dist/emit/format.js +0 -1
- package/dist/emit/frontend/frontend-react.d.ts +0 -1
- package/dist/emit/frontend/frontend-react.js +27 -10
- package/dist/emit/frontend/registry.d.ts +0 -1
- package/dist/emit/frontend/registry.js +0 -1
- package/dist/emit/frontend/runtime-emitter.d.ts +0 -1
- package/dist/emit/frontend/runtime-emitter.js +0 -1
- package/dist/emit/frontend/runtime-template.d.ts +0 -1
- package/dist/emit/frontend/runtime-template.js +0 -1
- package/dist/emit/frontend/ssg.d.ts +0 -1
- package/dist/emit/frontend/ssg.js +19 -9
- package/dist/emit/registry.d.ts +0 -1
- package/dist/emit/registry.js +0 -1
- package/dist/emit/static-site/css.d.ts +0 -1
- package/dist/emit/static-site/css.js +0 -1
- package/dist/emit/static-site/enhancements.d.ts +0 -1
- package/dist/emit/static-site/enhancements.js +0 -1
- package/dist/emit/static-site/static-site-html.d.ts +0 -1
- package/dist/emit/static-site/static-site-html.js +0 -1
- package/dist/emit/utils/sdk.d.ts +0 -1
- package/dist/emit/utils/sdk.js +0 -1
- package/dist/extensions/context.d.ts +0 -1
- package/dist/extensions/context.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/ir/decl/backend.raw.schema.d.ts +0 -1
- package/dist/ir/decl/backend.raw.schema.js +0 -1
- package/dist/ir/decl/bundle.d.ts +0 -1
- package/dist/ir/decl/bundle.js +0 -1
- package/dist/ir/decl/cli.raw.schema.d.ts +0 -1
- package/dist/ir/decl/cli.raw.schema.js +0 -1
- package/dist/ir/decl/frontend.raw.schema.d.ts +0 -1
- package/dist/ir/decl/frontend.raw.schema.js +0 -1
- package/dist/ir/decl/index.d.ts +0 -1
- package/dist/ir/decl/index.js +0 -1
- package/dist/ir/decl/normalize.schema.d.ts +0 -1
- package/dist/ir/decl/normalize.schema.js +0 -1
- package/dist/ir/domain/backend.d.ts +0 -1
- package/dist/ir/domain/backend.js +0 -1
- package/dist/ir/domain/cli.d.ts +0 -1
- package/dist/ir/domain/cli.js +0 -1
- package/dist/ir/domain/frontend/index.d.ts +0 -1
- package/dist/ir/domain/frontend/index.js +0 -1
- package/dist/ir/domain/frontend.d.ts +0 -1
- package/dist/ir/domain/frontend.js +0 -1
- package/dist/ir/frontend-contract.d.ts +0 -1
- package/dist/ir/frontend-contract.js +0 -1
- package/dist/ir/target/backend.d.ts +0 -1
- package/dist/ir/target/backend.js +0 -1
- package/dist/ir/target/backend.policy.d.ts +0 -1
- package/dist/ir/target/backend.policy.js +0 -1
- package/dist/ir/target/cli.d.ts +0 -1
- package/dist/ir/target/cli.js +0 -1
- package/dist/ir/target/electron.d.ts +0 -1
- package/dist/ir/target/electron.js +0 -1
- package/dist/ir/target/electron.policy.d.ts +0 -1
- package/dist/ir/target/electron.policy.js +0 -1
- package/dist/ir/target/frontend.d.ts +0 -1
- package/dist/ir/target/frontend.js +0 -1
- package/dist/ir/target/frontend.policy.d.ts +0 -1
- package/dist/ir/target/frontend.policy.js +0 -1
- package/dist/ir/target/index.d.ts +0 -1
- package/dist/ir/target/index.js +0 -1
- package/dist/ir/target/static-site.d.ts +0 -1
- package/dist/ir/target/static-site.js +0 -1
- package/dist/ir/target/static-site.policy.d.ts +0 -1
- package/dist/ir/target/static-site.policy.js +0 -1
- package/dist/lowering/backend.d.ts +0 -1
- package/dist/lowering/backend.js +0 -1
- package/dist/lowering/cli.d.ts +0 -1
- package/dist/lowering/cli.js +0 -1
- package/dist/lowering/engine.d.ts +0 -1
- package/dist/lowering/engine.js +0 -1
- package/dist/lowering/frontend.d.ts +0 -1
- package/dist/lowering/frontend.js +0 -1
- package/dist/lowering/targets/to-backend.d.ts +0 -1
- package/dist/lowering/targets/to-backend.js +0 -1
- package/dist/lowering/targets/to-cli.d.ts +0 -1
- package/dist/lowering/targets/to-cli.js +0 -1
- package/dist/lowering/targets/to-electron.d.ts +0 -1
- package/dist/lowering/targets/to-electron.js +0 -1
- package/dist/lowering/targets/to-frontend.d.ts +0 -1
- package/dist/lowering/targets/to-frontend.js +0 -1
- package/dist/lowering/targets/to-static-site.d.ts +0 -1
- package/dist/lowering/targets/to-static-site.js +0 -1
- package/dist/mappers/index.d.ts +1 -2
- package/dist/mappers/index.js +0 -1
- package/dist/types/extension.d.ts +0 -1
- package/dist/types/extension.js +0 -1
- package/dist/utils/array.d.ts +0 -1
- package/dist/utils/array.js +0 -1
- package/dist/utils/index.d.ts +2 -3
- package/dist/utils/index.js +2 -3
- package/dist/utils/string.d.ts +0 -1
- package/dist/utils/string.js +0 -1
- package/package.json +2 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/dsl/aggregator.d.ts.map +0 -1
- package/dist/dsl/aggregator.js.map +0 -1
- package/dist/dsl/frontend-runtime.d.ts.map +0 -1
- package/dist/dsl/frontend-runtime.js.map +0 -1
- package/dist/dsl/runtime.d.ts.map +0 -1
- package/dist/dsl/runtime.js.map +0 -1
- package/dist/emit/backend/adapters.d.ts.map +0 -1
- package/dist/emit/backend/adapters.js.map +0 -1
- package/dist/emit/backend/backend-tsmorph.d.ts.map +0 -1
- package/dist/emit/backend/backend-tsmorph.js.map +0 -1
- package/dist/emit/backend/fake-backend.d.ts.map +0 -1
- package/dist/emit/backend/fake-backend.js.map +0 -1
- package/dist/emit/backend/packaging.d.ts.map +0 -1
- package/dist/emit/backend/packaging.js.map +0 -1
- package/dist/emit/backend/server.d.ts.map +0 -1
- package/dist/emit/backend/server.js.map +0 -1
- package/dist/emit/cli/cli-fake.d.ts.map +0 -1
- package/dist/emit/cli/cli-fake.js.map +0 -1
- package/dist/emit/electron/electron-shell.d.ts.map +0 -1
- package/dist/emit/electron/electron-shell.js.map +0 -1
- package/dist/emit/engine.d.ts.map +0 -1
- package/dist/emit/engine.js.map +0 -1
- package/dist/emit/format.d.ts.map +0 -1
- package/dist/emit/format.js.map +0 -1
- package/dist/emit/frontend/frontend-react.d.ts.map +0 -1
- package/dist/emit/frontend/frontend-react.js.map +0 -1
- package/dist/emit/frontend/registry.d.ts.map +0 -1
- package/dist/emit/frontend/registry.js.map +0 -1
- package/dist/emit/frontend/runtime-emitter.d.ts.map +0 -1
- package/dist/emit/frontend/runtime-emitter.js.map +0 -1
- package/dist/emit/frontend/runtime-template.d.ts.map +0 -1
- package/dist/emit/frontend/runtime-template.js.map +0 -1
- package/dist/emit/frontend/ssg.d.ts.map +0 -1
- package/dist/emit/frontend/ssg.js.map +0 -1
- package/dist/emit/registry.d.ts.map +0 -1
- package/dist/emit/registry.js.map +0 -1
- package/dist/emit/static-site/css.d.ts.map +0 -1
- package/dist/emit/static-site/css.js.map +0 -1
- package/dist/emit/static-site/enhancements.d.ts.map +0 -1
- package/dist/emit/static-site/enhancements.js.map +0 -1
- package/dist/emit/static-site/static-site-html.d.ts.map +0 -1
- package/dist/emit/static-site/static-site-html.js.map +0 -1
- package/dist/emit/utils/sdk.d.ts.map +0 -1
- package/dist/emit/utils/sdk.js.map +0 -1
- package/dist/extensions/context.d.ts.map +0 -1
- package/dist/extensions/context.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/ir/decl/backend.raw.schema.d.ts.map +0 -1
- package/dist/ir/decl/backend.raw.schema.js.map +0 -1
- package/dist/ir/decl/bundle.d.ts.map +0 -1
- package/dist/ir/decl/bundle.js.map +0 -1
- package/dist/ir/decl/cli.raw.schema.d.ts.map +0 -1
- package/dist/ir/decl/cli.raw.schema.js.map +0 -1
- package/dist/ir/decl/frontend.raw.schema.d.ts.map +0 -1
- package/dist/ir/decl/frontend.raw.schema.js.map +0 -1
- package/dist/ir/decl/index.d.ts.map +0 -1
- package/dist/ir/decl/index.js.map +0 -1
- package/dist/ir/decl/normalize.schema.d.ts.map +0 -1
- package/dist/ir/decl/normalize.schema.js.map +0 -1
- package/dist/ir/domain/backend.d.ts.map +0 -1
- package/dist/ir/domain/backend.js.map +0 -1
- package/dist/ir/domain/cli.d.ts.map +0 -1
- package/dist/ir/domain/cli.js.map +0 -1
- package/dist/ir/domain/frontend/index.d.ts.map +0 -1
- package/dist/ir/domain/frontend/index.js.map +0 -1
- package/dist/ir/domain/frontend.d.ts.map +0 -1
- package/dist/ir/domain/frontend.js.map +0 -1
- package/dist/ir/frontend-contract.d.ts.map +0 -1
- package/dist/ir/frontend-contract.js.map +0 -1
- package/dist/ir/target/backend.d.ts.map +0 -1
- package/dist/ir/target/backend.js.map +0 -1
- package/dist/ir/target/backend.policy.d.ts.map +0 -1
- package/dist/ir/target/backend.policy.js.map +0 -1
- package/dist/ir/target/cli.d.ts.map +0 -1
- package/dist/ir/target/cli.js.map +0 -1
- package/dist/ir/target/electron.d.ts.map +0 -1
- package/dist/ir/target/electron.js.map +0 -1
- package/dist/ir/target/electron.policy.d.ts.map +0 -1
- package/dist/ir/target/electron.policy.js.map +0 -1
- package/dist/ir/target/frontend.d.ts.map +0 -1
- package/dist/ir/target/frontend.js.map +0 -1
- package/dist/ir/target/frontend.policy.d.ts.map +0 -1
- package/dist/ir/target/frontend.policy.js.map +0 -1
- package/dist/ir/target/index.d.ts.map +0 -1
- package/dist/ir/target/index.js.map +0 -1
- package/dist/ir/target/static-site.d.ts.map +0 -1
- package/dist/ir/target/static-site.js.map +0 -1
- package/dist/ir/target/static-site.policy.d.ts.map +0 -1
- package/dist/ir/target/static-site.policy.js.map +0 -1
- package/dist/lowering/backend.d.ts.map +0 -1
- package/dist/lowering/backend.js.map +0 -1
- package/dist/lowering/cli.d.ts.map +0 -1
- package/dist/lowering/cli.js.map +0 -1
- package/dist/lowering/engine.d.ts.map +0 -1
- package/dist/lowering/engine.js.map +0 -1
- package/dist/lowering/frontend.d.ts.map +0 -1
- package/dist/lowering/frontend.js.map +0 -1
- package/dist/lowering/targets/to-backend.d.ts.map +0 -1
- package/dist/lowering/targets/to-backend.js.map +0 -1
- package/dist/lowering/targets/to-cli.d.ts.map +0 -1
- package/dist/lowering/targets/to-cli.js.map +0 -1
- package/dist/lowering/targets/to-electron.d.ts.map +0 -1
- package/dist/lowering/targets/to-electron.js.map +0 -1
- package/dist/lowering/targets/to-frontend.d.ts.map +0 -1
- package/dist/lowering/targets/to-frontend.js.map +0 -1
- package/dist/lowering/targets/to-static-site.d.ts.map +0 -1
- package/dist/lowering/targets/to-static-site.js.map +0 -1
- package/dist/mappers/index.d.ts.map +0 -1
- package/dist/mappers/index.js.map +0 -1
- package/dist/types/extension.d.ts.map +0 -1
- package/dist/types/extension.js.map +0 -1
- package/dist/utils/array.d.ts.map +0 -1
- package/dist/utils/array.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/string.d.ts.map +0 -1
- package/dist/utils/string.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the `irgen` project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.1] - 2026-01-11
|
|
6
|
+
|
|
7
|
+
### GitHub Pages (SSG/Hybrid)
|
|
8
|
+
- Generate and build SSG/hybrid output for `examples/irgen-web.dsl.ts` in CI.
|
|
9
|
+
- Fix basePath handling so nav/docs links keep `/irgen` prefix after hydration.
|
|
10
|
+
- Add favicon/apple-touch-icon links in SSG output.
|
|
11
|
+
- Fix PWA manifest icon path and service worker cache paths under basePath.
|
|
12
|
+
- Set `SITE_URL` in Pages workflow for correct sitemap/robots URLs.
|
|
13
|
+
|
|
14
|
+
### Packaging
|
|
15
|
+
- Remove TypeScript sourcemaps and declaration maps from build output.
|
|
16
|
+
- Align README outputs with generated examples and keep example script in sync.
|
|
17
|
+
|
|
5
18
|
## [0.2.0] - 2026-01-11
|
|
6
19
|
|
|
7
20
|
### General Purpose Frontend & Headless Runtime (Phase 3)
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
package/dist/dsl/aggregator.d.ts
CHANGED
package/dist/dsl/aggregator.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
import { DeclFrontendAppSchema } from "../ir/decl/frontend.raw.schema.js";
|
|
4
|
-
|
|
4
|
+
// Use globalThis to share state across multiple module instances (e.g., src vs dist)
|
|
5
|
+
const _global = globalThis;
|
|
6
|
+
_global.__IR_CURRENT_FRONTEND = _global.__IR_CURRENT_FRONTEND || null;
|
|
5
7
|
function assert(cond, msg) {
|
|
6
8
|
if (!cond)
|
|
7
9
|
throw new Error(msg);
|
|
8
10
|
}
|
|
9
11
|
function mergePolicy(target, value) {
|
|
10
|
-
if (!
|
|
12
|
+
if (!_global.__IR_CURRENT_FRONTEND)
|
|
11
13
|
return;
|
|
12
|
-
|
|
13
|
-
const existing = (
|
|
14
|
-
|
|
14
|
+
_global.__IR_CURRENT_FRONTEND.meta = _global.__IR_CURRENT_FRONTEND.meta ?? {};
|
|
15
|
+
const existing = (_global.__IR_CURRENT_FRONTEND.meta.policies ?? {});
|
|
16
|
+
_global.__IR_CURRENT_FRONTEND.meta.policies = { ...existing, [target]: { ...(existing[target] ?? {}), ...value } };
|
|
15
17
|
}
|
|
16
18
|
const RUNTIME_HELPERS = [
|
|
17
19
|
"field",
|
|
@@ -38,28 +40,28 @@ function stripRuntimeHelpers(comp) {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
export function datasource(id, config) {
|
|
41
|
-
assert(
|
|
42
|
-
|
|
43
|
+
assert(_global.__IR_CURRENT_FRONTEND, "datasource() harus di dalam frontend()");
|
|
44
|
+
_global.__IR_CURRENT_FRONTEND.datasources.push({ id, ...config });
|
|
43
45
|
}
|
|
44
46
|
export function operation(id, config) {
|
|
45
|
-
assert(
|
|
46
|
-
|
|
47
|
+
assert(_global.__IR_CURRENT_FRONTEND, "operation() harus di dalam frontend()");
|
|
48
|
+
_global.__IR_CURRENT_FRONTEND.operations.push({ id, ...config });
|
|
47
49
|
}
|
|
48
50
|
export function resource(id, config) {
|
|
49
|
-
assert(
|
|
50
|
-
|
|
51
|
+
assert(_global.__IR_CURRENT_FRONTEND, "resource() harus di dalam frontend()");
|
|
52
|
+
_global.__IR_CURRENT_FRONTEND.resources.push({ id, ...config });
|
|
51
53
|
}
|
|
52
54
|
export function meta(key, value) {
|
|
53
|
-
assert(
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
assert(_global.__IR_CURRENT_FRONTEND, "meta() harus di dalam frontend()");
|
|
56
|
+
_global.__IR_CURRENT_FRONTEND.meta = _global.__IR_CURRENT_FRONTEND.meta ?? {};
|
|
57
|
+
_global.__IR_CURRENT_FRONTEND.meta[key] = value;
|
|
56
58
|
}
|
|
57
59
|
export function policy(target, value) {
|
|
58
|
-
assert(
|
|
60
|
+
assert(_global.__IR_CURRENT_FRONTEND, "policy() harus di dalam frontend()");
|
|
59
61
|
mergePolicy(target, value);
|
|
60
62
|
}
|
|
61
63
|
export function page(pName, opts, cb) {
|
|
62
|
-
assert(
|
|
64
|
+
assert(_global.__IR_CURRENT_FRONTEND, "page() harus di dalam frontend()");
|
|
63
65
|
const page = {
|
|
64
66
|
type: "page",
|
|
65
67
|
name: pName,
|
|
@@ -110,16 +112,16 @@ export function page(pName, opts, cb) {
|
|
|
110
112
|
}
|
|
111
113
|
const finalized = comp;
|
|
112
114
|
page.components.push(finalized);
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
+
if (_global.__IR_CURRENT_FRONTEND)
|
|
116
|
+
_global.__IR_CURRENT_FRONTEND.components.push(finalized);
|
|
115
117
|
}
|
|
116
118
|
});
|
|
117
119
|
}
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
+
if (_global.__IR_CURRENT_FRONTEND)
|
|
121
|
+
_global.__IR_CURRENT_FRONTEND.pages.push(page);
|
|
120
122
|
}
|
|
121
123
|
export function component(name, cb) {
|
|
122
|
-
assert(
|
|
124
|
+
assert(_global.__IR_CURRENT_FRONTEND, "component() harus di dalam frontend()");
|
|
123
125
|
const comp = { type: "component", name: name, props: {}, form: { fields: [] } };
|
|
124
126
|
// add convenience methods to the comp object for DSL users: field() and prop()
|
|
125
127
|
comp.field = function (fieldName, type, label, validators, config) {
|
|
@@ -155,8 +157,8 @@ export function component(name, cb) {
|
|
|
155
157
|
if (comp.html) {
|
|
156
158
|
throw new Error(`component.html is not allowed (component: ${comp.name}). Use component.content with Markdown instead.`);
|
|
157
159
|
}
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
+
if (_global.__IR_CURRENT_FRONTEND)
|
|
161
|
+
_global.__IR_CURRENT_FRONTEND.components.push(comp);
|
|
160
162
|
}
|
|
161
163
|
export function frontend(name, optsOrFn, maybeFn) {
|
|
162
164
|
assert(typeof name === "string" && name.length > 0, "frontend(name) harus string");
|
|
@@ -164,7 +166,7 @@ export function frontend(name, optsOrFn, maybeFn) {
|
|
|
164
166
|
const fn = (typeof optsOrFn === "function" ? optsOrFn : maybeFn);
|
|
165
167
|
assert(typeof fn === "function", "frontend(..., fn) fn harus function");
|
|
166
168
|
const baseMeta = opts?.meta ?? {};
|
|
167
|
-
|
|
169
|
+
_global.__IR_CURRENT_FRONTEND = {
|
|
168
170
|
type: "frontend",
|
|
169
171
|
name,
|
|
170
172
|
basePath: opts?.basePath ?? "/",
|
|
@@ -190,15 +192,15 @@ export function frontend(name, optsOrFn, maybeFn) {
|
|
|
190
192
|
meta,
|
|
191
193
|
policy,
|
|
192
194
|
});
|
|
193
|
-
const parsed = DeclFrontendAppSchema.parse(
|
|
194
|
-
|
|
195
|
+
const parsed = DeclFrontendAppSchema.parse(_global.__IR_CURRENT_FRONTEND);
|
|
196
|
+
_global.__IR_CURRENT_FRONTEND = parsed;
|
|
195
197
|
return parsed;
|
|
196
198
|
}
|
|
197
199
|
export async function loadFrontendDsl(entry) {
|
|
198
200
|
const abs = path.resolve(process.cwd(), entry);
|
|
199
201
|
const url = pathToFileURL(abs).href;
|
|
200
202
|
// reset
|
|
201
|
-
|
|
203
|
+
_global.__IR_CURRENT_FRONTEND = null;
|
|
202
204
|
try {
|
|
203
205
|
await import(url);
|
|
204
206
|
}
|
|
@@ -224,9 +226,8 @@ export async function loadFrontendDsl(entry) {
|
|
|
224
226
|
throw new Error(`Failed to load frontend DSL (${entry}): ${err2?.message ?? err2}`);
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
|
-
if (!
|
|
229
|
+
if (!_global.__IR_CURRENT_FRONTEND)
|
|
228
230
|
throw new Error(`Frontend DSL did not call frontend(...)`);
|
|
229
|
-
const parsed = DeclFrontendAppSchema.parse(
|
|
231
|
+
const parsed = DeclFrontendAppSchema.parse(_global.__IR_CURRENT_FRONTEND);
|
|
230
232
|
return parsed;
|
|
231
233
|
}
|
|
232
|
-
//# sourceMappingURL=frontend-runtime.js.map
|
package/dist/dsl/runtime.d.ts
CHANGED
package/dist/dsl/runtime.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
import { DeclAppSchema } from "../ir/decl/backend.raw.schema.js";
|
|
4
|
-
|
|
4
|
+
// Use globalThis to share state across multiple module instances (e.g., src vs dist)
|
|
5
|
+
const _global = globalThis;
|
|
6
|
+
_global.__IR_CURRENT_BACKEND = _global.__IR_CURRENT_BACKEND || null;
|
|
5
7
|
function assert(cond, msg) {
|
|
6
8
|
if (!cond)
|
|
7
9
|
throw new Error(msg);
|
|
@@ -11,18 +13,18 @@ function defaultEntityId(name) {
|
|
|
11
13
|
return `${kebab(name)}`;
|
|
12
14
|
}
|
|
13
15
|
function mergePolicy(target, value) {
|
|
14
|
-
if (!
|
|
16
|
+
if (!_global.__IR_CURRENT_BACKEND)
|
|
15
17
|
return;
|
|
16
|
-
|
|
17
|
-
const existing = (
|
|
18
|
-
|
|
18
|
+
_global.__IR_CURRENT_BACKEND.meta = _global.__IR_CURRENT_BACKEND.meta ?? {};
|
|
19
|
+
const existing = (_global.__IR_CURRENT_BACKEND.meta.policies ?? {});
|
|
20
|
+
_global.__IR_CURRENT_BACKEND.meta.policies = { ...existing, [target]: { ...(existing[target] ?? {}), ...value } };
|
|
19
21
|
}
|
|
20
22
|
export function app(name, optsOrFn, maybeFn) {
|
|
21
23
|
assert(typeof name === "string" && name.length > 0, "app(name) harus string");
|
|
22
24
|
const opts = (typeof optsOrFn === "function" ? {} : optsOrFn) ?? {};
|
|
23
25
|
const fn = (typeof optsOrFn === "function" ? optsOrFn : maybeFn);
|
|
24
26
|
assert(typeof fn === "function", "app(..., fn) fn harus function");
|
|
25
|
-
|
|
27
|
+
_global.__IR_CURRENT_BACKEND = { type: "app", name, entities: [], meta: { ...(opts.meta ?? {}) } };
|
|
26
28
|
if (opts.policies) {
|
|
27
29
|
for (const [target, value] of Object.entries(opts.policies)) {
|
|
28
30
|
mergePolicy(target, value);
|
|
@@ -30,7 +32,7 @@ export function app(name, optsOrFn, maybeFn) {
|
|
|
30
32
|
}
|
|
31
33
|
fn({
|
|
32
34
|
entity(entityName, entityFn) {
|
|
33
|
-
assert(
|
|
35
|
+
assert(_global.__IR_CURRENT_BACKEND, "entity() harus di dalam app()");
|
|
34
36
|
const entity = {
|
|
35
37
|
type: "entity",
|
|
36
38
|
name: entityName,
|
|
@@ -67,14 +69,14 @@ export function app(name, optsOrFn, maybeFn) {
|
|
|
67
69
|
},
|
|
68
70
|
};
|
|
69
71
|
entityFn(eb);
|
|
70
|
-
|
|
72
|
+
_global.__IR_CURRENT_BACKEND.entities.push(entity);
|
|
71
73
|
},
|
|
72
74
|
meta(key, value) {
|
|
73
|
-
assert(
|
|
74
|
-
|
|
75
|
+
assert(_global.__IR_CURRENT_BACKEND, "meta() harus di dalam app()");
|
|
76
|
+
_global.__IR_CURRENT_BACKEND.meta[key] = value;
|
|
75
77
|
},
|
|
76
78
|
policy(target, value) {
|
|
77
|
-
assert(
|
|
79
|
+
assert(_global.__IR_CURRENT_BACKEND, "policy() harus di dalam app()");
|
|
78
80
|
mergePolicy(target, value);
|
|
79
81
|
},
|
|
80
82
|
});
|
|
@@ -88,7 +90,7 @@ export async function loadDsl(entry) {
|
|
|
88
90
|
const abs = path.resolve(process.cwd(), entry);
|
|
89
91
|
const url = pathToFileURL(abs).href;
|
|
90
92
|
// reset
|
|
91
|
-
|
|
93
|
+
_global.__IR_CURRENT_BACKEND = null;
|
|
92
94
|
try {
|
|
93
95
|
await import(url);
|
|
94
96
|
}
|
|
@@ -112,9 +114,8 @@ export async function loadDsl(entry) {
|
|
|
112
114
|
throw new Error(`Failed to load DSL (${entry}): ${errMessage2}`);
|
|
113
115
|
}
|
|
114
116
|
}
|
|
115
|
-
assert(
|
|
117
|
+
assert(_global.__IR_CURRENT_BACKEND, `DSL tidak memanggil app(...) — file: ${entry}`);
|
|
116
118
|
// validate + normalize
|
|
117
|
-
const parsed = DeclAppSchema.parse(
|
|
119
|
+
const parsed = DeclAppSchema.parse(_global.__IR_CURRENT_BACKEND);
|
|
118
120
|
return parsed;
|
|
119
121
|
}
|
|
120
|
-
//# sourceMappingURL=runtime.js.map
|
|
@@ -8,4 +8,3 @@ export declare function emitPaginationAdapter(project: Project, outDir: string,
|
|
|
8
8
|
export declare function emitValidationAdapter(project: Project, outDir: string, policies?: any): void;
|
|
9
9
|
export declare function emitResponseAdapter(project: Project, outDir: string, policies?: any): void;
|
|
10
10
|
export declare function emitAuthAdapter(project: Project, outDir: string, policies?: any): void;
|
|
11
|
-
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -2,4 +2,3 @@ import { Project } from "ts-morph";
|
|
|
2
2
|
import type { BackendTargetIR } from "../../ir/target/backend.js";
|
|
3
3
|
export declare function emitBackendToProject(project: Project, outDir: string, ir: BackendTargetIR): void;
|
|
4
4
|
export declare function emitBackend(ir: BackendTargetIR, outDir: string): void;
|
|
5
|
-
//# sourceMappingURL=backend-tsmorph.d.ts.map
|
package/dist/emit/engine.d.ts
CHANGED
package/dist/emit/engine.js
CHANGED
package/dist/emit/format.d.ts
CHANGED
package/dist/emit/format.js
CHANGED
|
@@ -281,6 +281,9 @@ function emitPwaAssets(outDir, ir) {
|
|
|
281
281
|
if (!ir.pwa?.enabled)
|
|
282
282
|
return;
|
|
283
283
|
const pwa = ir.pwa;
|
|
284
|
+
const basePath = ir.policies.frontend.framework.rendering.basePath || "/";
|
|
285
|
+
const swBasePath = basePath === "/" ? "" : basePath.replace(/\/$/, "");
|
|
286
|
+
const manifestIconPath = basePath === "/" ? "/icons/icon.svg" : `${basePath.replace(/\/$/, "")}/icons/icon.svg`;
|
|
284
287
|
const manifest = {
|
|
285
288
|
name: pwa.name,
|
|
286
289
|
short_name: pwa.shortName,
|
|
@@ -292,7 +295,7 @@ function emitPwaAssets(outDir, ir) {
|
|
|
292
295
|
theme_color: pwa.themeColor,
|
|
293
296
|
orientation: pwa.orientation,
|
|
294
297
|
icons: pwa.icons ?? [
|
|
295
|
-
{ src:
|
|
298
|
+
{ src: manifestIconPath, sizes: "any", type: "image/svg+xml" },
|
|
296
299
|
],
|
|
297
300
|
};
|
|
298
301
|
const publicDir = path.join(outDir, "public");
|
|
@@ -314,7 +317,11 @@ function emitPwaAssets(outDir, ir) {
|
|
|
314
317
|
fs.writeFileSync(path.join(iconsDir, "icon.svg"), svgIcon, "utf-8");
|
|
315
318
|
const sw = `
|
|
316
319
|
const CACHE_NAME = "irgen-pwa-v1";
|
|
317
|
-
const ASSETS = [
|
|
320
|
+
const ASSETS = [
|
|
321
|
+
"${swBasePath}/",
|
|
322
|
+
"${swBasePath}/index.html",
|
|
323
|
+
"${swBasePath}/manifest.webmanifest"
|
|
324
|
+
];
|
|
318
325
|
|
|
319
326
|
self.addEventListener("install", (event) => {
|
|
320
327
|
event.waitUntil(
|
|
@@ -337,7 +344,7 @@ self.addEventListener("fetch", (event) => {
|
|
|
337
344
|
const copy = resp.clone();
|
|
338
345
|
caches.open(CACHE_NAME).then((cache) => cache.put(event.request, copy));
|
|
339
346
|
return resp;
|
|
340
|
-
}).catch(() => caches.match("/index.html"));
|
|
347
|
+
}).catch(() => caches.match("${swBasePath}/index.html"));
|
|
341
348
|
})
|
|
342
349
|
);
|
|
343
350
|
});
|
|
@@ -353,7 +360,7 @@ import { defineConfig } from "vite";
|
|
|
353
360
|
import react from "@vitejs/plugin-react";
|
|
354
361
|
|
|
355
362
|
export default defineConfig({
|
|
356
|
-
base: "
|
|
363
|
+
base: "${policy.framework.rendering.basePath}",
|
|
357
364
|
plugins: [react()],
|
|
358
365
|
resolve: {
|
|
359
366
|
dedupe: ["react", "react-dom", "react-router", "react-router-dom"],
|
|
@@ -366,7 +373,7 @@ export default defineConfig({
|
|
|
366
373
|
manifest: true,
|
|
367
374
|
},
|
|
368
375
|
ssr: {
|
|
369
|
-
noExternal: ["react", "react-dom", "react-router", "react-router-dom"],
|
|
376
|
+
noExternal: ["react", "react-dom", "react-router", "react-router-dom", /react-syntax-highlighter/, /lucide-react/, "prismjs"],
|
|
370
377
|
},` : ""}
|
|
371
378
|
});
|
|
372
379
|
`.trim();
|
|
@@ -421,7 +428,10 @@ export function emitFrontend(project, outDir, ir) {
|
|
|
421
428
|
clientEntry.addImportDeclaration({ moduleSpecifier: "prismjs/components/prism-bash" });
|
|
422
429
|
clientEntry.addImportDeclaration({ moduleSpecifier: "prismjs/components/prism-css" });
|
|
423
430
|
}
|
|
424
|
-
const
|
|
431
|
+
const policyBasePath = policy.framework.rendering.basePath || "/";
|
|
432
|
+
const irBasePath = ir.basePath || "/";
|
|
433
|
+
const basePathRaw = policyBasePath !== "/" ? policyBasePath : irBasePath;
|
|
434
|
+
const basePath = basePathRaw.replace(/\/$/, "") || "/";
|
|
425
435
|
const hasBasePath = basePath !== "/";
|
|
426
436
|
if (mode === "hybrid") {
|
|
427
437
|
clientEntry.addStatements(`
|
|
@@ -465,10 +475,11 @@ root.render(
|
|
|
465
475
|
`.trim());
|
|
466
476
|
}
|
|
467
477
|
if (ir.pwa?.enabled) {
|
|
478
|
+
const swBasePath = basePath !== "/" ? basePath : "";
|
|
468
479
|
clientEntry.addStatements(`
|
|
469
480
|
if ('serviceWorker' in navigator) {
|
|
470
481
|
window.addEventListener('load', () => {
|
|
471
|
-
navigator.serviceWorker.register('/pwa-sw.js').catch(err => {
|
|
482
|
+
navigator.serviceWorker.register('${swBasePath}/pwa-sw.js').catch(err => {
|
|
472
483
|
console.error('Service worker registration failed', err);
|
|
473
484
|
});
|
|
474
485
|
});
|
|
@@ -511,6 +522,8 @@ if ('serviceWorker' in navigator) {
|
|
|
511
522
|
writer.writeLine("const [tocItems, setTocItems] = useState([] as Array<{ id: string; text: string; level: number }>);");
|
|
512
523
|
writer.writeLine("const [activeToc, setActiveToc] = useState(\"\" as string);");
|
|
513
524
|
writer.writeLine("const location = useLocation();");
|
|
525
|
+
writer.writeLine(`const basePath = "${policy.framework.rendering.basePath}".replace(/\\/$/, "") || "/";`);
|
|
526
|
+
writer.writeLine("const relativePath = location.pathname.startsWith(basePath) ? location.pathname.substring(basePath.length) || '/' : location.pathname;");
|
|
514
527
|
writer.writeLine(`const docsLinks = ${JSON.stringify(docsLinks, null, 2)};`);
|
|
515
528
|
writer.writeLine(`const defaultDocsGroupLabel = ${JSON.stringify(docsGroupLabel)};`);
|
|
516
529
|
writer.writeLine("const docsSidebarGroups = docsLinks.reduce((acc, link) => {");
|
|
@@ -521,7 +534,7 @@ if ('serviceWorker' in navigator) {
|
|
|
521
534
|
writer.writeLine(" return acc;");
|
|
522
535
|
writer.writeLine("}, [] as Array<{ label: string; items: typeof docsLinks }>)");
|
|
523
536
|
writer.writeLine("const docsPaths = docsLinks.map((link) => link.path);");
|
|
524
|
-
writer.writeLine("const isDocsRoute = docsPaths.includes(
|
|
537
|
+
writer.writeLine("const isDocsRoute = docsPaths.includes(relativePath);");
|
|
525
538
|
writer.writeLine("");
|
|
526
539
|
writer.writeLine("useEffect(() => {");
|
|
527
540
|
writer.writeLine(" if (isDark) {");
|
|
@@ -727,13 +740,18 @@ if ('serviceWorker' in navigator) {
|
|
|
727
740
|
writer.writeLine(" );");
|
|
728
741
|
});
|
|
729
742
|
// index.html (SPA fallback / CSR entry)
|
|
743
|
+
// Note: Vite handles prefixing based on 'base' config during build.
|
|
744
|
+
// Scripts in index.html should point to the source path relative to project root.
|
|
745
|
+
const htmlBasePath = basePath !== "/" ? basePath : "";
|
|
730
746
|
project.createSourceFile(path.join(outDir, "index.html"), `
|
|
731
747
|
<!DOCTYPE html>
|
|
732
748
|
<html lang="en">
|
|
733
749
|
<head>
|
|
734
750
|
<meta charset="UTF-8" />
|
|
735
751
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
736
|
-
${ir.pwa?.enabled ? `<link rel="manifest" href="/manifest.webmanifest" />` : ""}
|
|
752
|
+
${ir.pwa?.enabled ? `<link rel="manifest" href="${htmlBasePath}/manifest.webmanifest" />` : ""}
|
|
753
|
+
${ir.pwa?.enabled ? `<link rel="icon" href="${htmlBasePath}/icons/icon.svg" />` : ""}
|
|
754
|
+
${ir.pwa?.enabled ? `<link rel="apple-touch-icon" href="${htmlBasePath}/icons/icon.svg" />` : ""}
|
|
737
755
|
${ir.pwa?.enabled ? `<meta name="theme-color" content="${ir.pwa.themeColor}" />` : ""}
|
|
738
756
|
<title>${ir.appName}</title>
|
|
739
757
|
</head>
|
|
@@ -2018,4 +2036,3 @@ function emitMarketingComponent(writer, m, policy) {
|
|
|
2018
2036
|
writer.writeLine(` </div>`);
|
|
2019
2037
|
}
|
|
2020
2038
|
}
|
|
2021
|
-
//# sourceMappingURL=frontend-react.js.map
|
|
@@ -5,4 +5,3 @@ import type { FrontendPolicy } from "../../ir/target/frontend.policy.js";
|
|
|
5
5
|
export declare function isInteractiveComponent(component: FrontendComponent): boolean;
|
|
6
6
|
export declare function inferInteractiveRoutes(ir: FrontendTargetIR, policy: FrontendPolicy): string[];
|
|
7
7
|
export declare function emitSsgSupport(project: Project, outDir: string, frontendDir: string, ir: FrontendTargetIR): void;
|
|
8
|
-
//# sourceMappingURL=ssg.d.ts.map
|
|
@@ -60,10 +60,14 @@ export function emitSsgSupport(project, outDir, frontendDir, ir) {
|
|
|
60
60
|
serverEntry.addImportDeclaration({ moduleSpecifier: "react-router-dom/server", namedImports: ["StaticRouter"] });
|
|
61
61
|
serverEntry.addImportDeclaration({ moduleSpecifier: "./App", namedImports: ["App"] });
|
|
62
62
|
serverEntry.addStatements(`
|
|
63
|
+
const basePath = "${policy.framework.rendering.basePath}".replace(/\\/$/, "");
|
|
64
|
+
const hasBasePath = basePath && basePath !== "/";
|
|
65
|
+
|
|
63
66
|
export function render(url: string) {
|
|
67
|
+
const location = hasBasePath ? \`\${basePath}\${url}\` : url;
|
|
64
68
|
const html = renderToString(
|
|
65
69
|
<React.StrictMode>
|
|
66
|
-
<StaticRouter location={
|
|
70
|
+
<StaticRouter location={location} basename={hasBasePath ? basePath : undefined}>
|
|
67
71
|
<App />
|
|
68
72
|
</StaticRouter>
|
|
69
73
|
</React.StrictMode>
|
|
@@ -78,7 +82,9 @@ export function render(url: string) {
|
|
|
78
82
|
<head>
|
|
79
83
|
<meta charset="UTF-8" />
|
|
80
84
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
81
|
-
${ir.pwa?.enabled ? `<link rel="manifest" href="/manifest.webmanifest" />` : ""}
|
|
85
|
+
${ir.pwa?.enabled ? `<link rel="manifest" href="${policy.framework.rendering.basePath.replace(/\/$/, "")}/manifest.webmanifest" />` : ""}
|
|
86
|
+
${ir.pwa?.enabled ? `<link rel="icon" href="${policy.framework.rendering.basePath.replace(/\/$/, "")}/icons/icon.svg" />` : ""}
|
|
87
|
+
${ir.pwa?.enabled ? `<link rel="apple-touch-icon" href="${policy.framework.rendering.basePath.replace(/\/$/, "")}/icons/icon.svg" />` : ""}
|
|
82
88
|
${ir.pwa?.enabled ? `<meta name="theme-color" content="${ir.pwa.themeColor}" />` : ""}
|
|
83
89
|
<!--app-head-->
|
|
84
90
|
<title>${ir.appName}</title>
|
|
@@ -139,19 +145,20 @@ function resolveEntry(manifest) {
|
|
|
139
145
|
function buildHead(entry, manifest, shouldHydrate) {
|
|
140
146
|
if (!entry) return "";
|
|
141
147
|
const tags = [];
|
|
148
|
+
const base = "${policy.framework.rendering.basePath}".replace(/\\/$/, "");
|
|
142
149
|
if (entry.css) {
|
|
143
150
|
for (const css of entry.css) {
|
|
144
|
-
tags.push(\`<link rel="stylesheet" href="/\${css}">\`);
|
|
151
|
+
tags.push(\`<link rel="stylesheet" href="\${base}/\${css}">\`);
|
|
145
152
|
}
|
|
146
153
|
}
|
|
147
154
|
if (shouldHydrate && entry.imports) {
|
|
148
155
|
for (const imp of entry.imports) {
|
|
149
156
|
const file = manifest?.[imp]?.file ?? null;
|
|
150
|
-
if (file) tags.push(\`<link rel="modulepreload" href="/\${file}">\`);
|
|
157
|
+
if (file) tags.push(\`<link rel="modulepreload" href="\${base}/\${file}">\`);
|
|
151
158
|
}
|
|
152
159
|
}
|
|
153
160
|
if (shouldHydrate && entry.file) {
|
|
154
|
-
tags.push(\`<script type="module" src="/\${entry.file}"></script>\`);
|
|
161
|
+
tags.push(\`<script type="module" src="\${base}/\${entry.file}"></script>\`);
|
|
155
162
|
}
|
|
156
163
|
return tags.join("\\n ");
|
|
157
164
|
}
|
|
@@ -188,10 +195,14 @@ async function prerender() {
|
|
|
188
195
|
fs.writeFileSync(outFile, finalHtml, "utf-8");
|
|
189
196
|
}
|
|
190
197
|
|
|
198
|
+
const base = "${policy.framework.rendering.basePath}".replace(/\\/$/, "");
|
|
191
199
|
if (emitSitemap) {
|
|
192
200
|
const urls = routes
|
|
193
201
|
.filter((r) => !isDynamicRoute(r))
|
|
194
|
-
.map((route) =>
|
|
202
|
+
.map((route) => {
|
|
203
|
+
const fullPath = (base + route).replace(/\\/\\//g, "/");
|
|
204
|
+
return \` <url><loc>\${new URL(fullPath, siteUrl).href}</loc></url>\`;
|
|
205
|
+
})
|
|
195
206
|
.join("\\n");
|
|
196
207
|
const sitemap = \`<?xml version="1.0" encoding="UTF-8"?>
|
|
197
208
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
@@ -201,9 +212,9 @@ async function prerender() {
|
|
|
201
212
|
}
|
|
202
213
|
|
|
203
214
|
if (emitRobotsTxt) {
|
|
204
|
-
const sitemapUrl = emitSitemap ? new URL("/sitemap.xml", siteUrl).href : null;
|
|
215
|
+
const sitemapUrl = emitSitemap ? new URL((base + "/sitemap.xml").replace(/\\/\\//g, "/"), siteUrl).href : null;
|
|
205
216
|
const robotsTxt = \`User-agent: *
|
|
206
|
-
Allow: /
|
|
217
|
+
Allow: \${base || "/"}
|
|
207
218
|
\${sitemapUrl ? "\\nSitemap: " + sitemapUrl : ""}\`;
|
|
208
219
|
fs.writeFileSync(path.join(outDir, "robots.txt"), robotsTxt, "utf-8");
|
|
209
220
|
}
|
|
@@ -216,4 +227,3 @@ prerender().catch((err) => {
|
|
|
216
227
|
`.trim();
|
|
217
228
|
fs.writeFileSync(path.join(scriptDir, "prerender.mjs"), prerenderScript, "utf-8");
|
|
218
229
|
}
|
|
219
|
-
//# sourceMappingURL=ssg.js.map
|