@zintrust/core 0.4.8 → 0.4.10
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/package.json +1 -1
- package/src/boot/bootstrap.js +7 -0
- package/src/boot/registry/registerRoute.d.ts.map +1 -1
- package/src/boot/registry/registerRoute.js +23 -0
- package/src/bootstrap/service-manifest.d.ts +4 -0
- package/src/bootstrap/service-manifest.d.ts.map +1 -0
- package/src/bootstrap/service-manifest.js +2 -0
- package/src/cli/commands/InitContainerCommand.d.ts.map +1 -1
- package/src/cli/commands/InitContainerCommand.js +1 -60
- package/src/cli/commands/MigrateCommand.js +1 -1
- package/src/cli/commands/RoutesCommand.d.ts.map +1 -1
- package/src/cli/commands/RoutesCommand.js +36 -1
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +73 -35
- package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/RouteGenerator.js +4 -2
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +147 -29
- package/src/common/ExternalServiceUtils.d.ts +2 -2
- package/src/functions/cloudflare.d.ts.map +1 -1
- package/src/functions/cloudflare.js +76 -16
- package/src/index.d.ts +16 -13
- package/src/index.d.ts.map +1 -1
- package/src/index.js +16 -14
- package/src/microservices/MicroserviceBootstrap.d.ts +1 -0
- package/src/microservices/MicroserviceBootstrap.d.ts.map +1 -1
- package/src/microservices/MicroserviceBootstrap.js +51 -7
- package/src/microservices/MicroserviceGenerator.d.ts.map +1 -1
- package/src/microservices/MicroserviceGenerator.js +12 -14
- package/src/microservices/MicroserviceManager.d.ts +1 -0
- package/src/microservices/MicroserviceManager.d.ts.map +1 -1
- package/src/microservices/MicroserviceManager.js +85 -62
- package/src/microservices/ServiceManifest.d.ts +50 -0
- package/src/microservices/ServiceManifest.d.ts.map +1 -0
- package/src/microservices/ServiceManifest.js +82 -0
- package/src/runtime/OverrideValueMerge.d.ts +3 -0
- package/src/runtime/OverrideValueMerge.d.ts.map +1 -0
- package/src/runtime/OverrideValueMerge.js +14 -0
- package/src/runtime/PluginAutoImports.d.ts.map +1 -1
- package/src/runtime/PluginAutoImports.js +1 -5
- package/src/runtime/ProjectRuntime.d.ts +13 -0
- package/src/runtime/ProjectRuntime.d.ts.map +1 -0
- package/src/runtime/ProjectRuntime.js +111 -0
- package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -1
- package/src/runtime/StartupConfigFileRegistry.js +33 -8
- package/src/scripts/TemplateImportsCheck.js +0 -2
- package/src/start.d.ts +3 -0
- package/src/start.d.ts.map +1 -1
- package/src/start.js +17 -0
- package/src/templates/project/basic/src/bootstrap/service-manifest.ts.tpl +5 -0
- package/src/templates/project/basic/src/zintrust.runtime.ts.tpl +9 -0
- package/src/templates/project/basic/src/zintrust.runtime.wg.ts.tpl +9 -0
- package/src/templates/project/basic/wrangler.jsonc.tpl +1 -0
- package/src/zintrust.comon.d.ts +9 -0
- package/src/zintrust.comon.d.ts.map +1 -0
- package/src/zintrust.comon.js +15 -0
- package/src/zintrust.plugins.d.ts +6 -3
- package/src/zintrust.plugins.d.ts.map +1 -1
- package/src/zintrust.plugins.js +27 -3
- package/src/zintrust.runtime.d.ts +4 -0
- package/src/zintrust.runtime.d.ts.map +1 -0
- package/src/zintrust.runtime.js +3 -0
- package/src/zintrust.runtime.wg.d.ts +4 -0
- package/src/zintrust.runtime.wg.d.ts.map +1 -0
- package/src/zintrust.runtime.wg.js +3 -0
package/package.json
CHANGED
package/src/boot/bootstrap.js
CHANGED
|
@@ -9,6 +9,7 @@ import { appConfig } from '../config/app.js';
|
|
|
9
9
|
import { Env } from '../config/env.js';
|
|
10
10
|
import { Logger } from '../config/logger.js';
|
|
11
11
|
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
12
|
+
import { ProjectRuntime } from '../runtime/ProjectRuntime.js';
|
|
12
13
|
import { loadWorkersModule } from '../runtime/WorkersModule.js';
|
|
13
14
|
let appInstance;
|
|
14
15
|
let serverInstance;
|
|
@@ -211,6 +212,12 @@ const BootstrapFunctions = Object.freeze({
|
|
|
211
212
|
// best-effort; run without plugins if loader fails (e.g. non-Node runtime)
|
|
212
213
|
Logger.warn('Plugin auto-imports loader skipped:', error);
|
|
213
214
|
}
|
|
215
|
+
try {
|
|
216
|
+
await ProjectRuntime.tryLoadNodeRuntime();
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
Logger.warn('Project runtime hook loader skipped:', error);
|
|
220
|
+
}
|
|
214
221
|
// Create application instance
|
|
215
222
|
// if (Env.ZINTRUST_PROJECT_ROOT) {
|
|
216
223
|
// }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerRoute.d.ts","sourceRoot":"","sources":["../../../../src/boot/registry/registerRoute.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"registerRoute.d.ts","sourceRoot":"","sources":["../../../../src/boot/registry/registerRoute.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAUnD,eAAO,MAAM,kBAAkB,QAAO,OAKrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAMpF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,CAAC,EAAE,YAAY,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAOrF,CAAC;AAuFF,eAAO,MAAM,oBAAoB,GAC/B,kBAAkB,MAAM,EACxB,QAAQ,OAAO,KACd,OAAO,CAAC,IAAI,CAoBd,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { appConfig } from '../../config/index.js';
|
|
2
2
|
import Logger from '../../config/logger.js';
|
|
3
|
+
import { isObject } from '../../helper/index.js';
|
|
3
4
|
import * as path from '../../node-singletons/path.js';
|
|
4
5
|
import { pathToFileURL } from '../../node-singletons/url.js';
|
|
5
6
|
import { detectRuntime } from '../../runtime/detectRuntime.js';
|
|
7
|
+
import { ProjectRuntime } from '../../runtime/ProjectRuntime.js';
|
|
6
8
|
const isCloudflare = detectRuntime().isCloudflare;
|
|
7
9
|
export const isCompiledJsModule = () => {
|
|
8
10
|
// When running from dist, this module is compiled to .js and Node ESM resolution
|
|
@@ -59,6 +61,26 @@ const registerAppRoutes = async (resolvedBasePath, router) => {
|
|
|
59
61
|
mod.registerRoutes(router);
|
|
60
62
|
}
|
|
61
63
|
};
|
|
64
|
+
const registerManifestRoutes = async (router) => {
|
|
65
|
+
const serviceManifest = ProjectRuntime.getServiceManifest();
|
|
66
|
+
if (serviceManifest.length === 0)
|
|
67
|
+
return;
|
|
68
|
+
for (const entry of serviceManifest) {
|
|
69
|
+
if (entry.monolithEnabled === false || typeof entry.loadRoutes !== 'function') {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
// eslint-disable-next-line no-await-in-loop
|
|
74
|
+
const mod = await entry.loadRoutes();
|
|
75
|
+
if (isObject(mod) && typeof mod.registerRoutes === 'function') {
|
|
76
|
+
mod.registerRoutes(router);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
Logger.warn(`Failed to register manifest routes for ${entry.id}`, error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
62
84
|
const registerFrameworkRoutes = async (resolvedBasePath, router) => {
|
|
63
85
|
const frameworkRoutes = await tryImportRoutesFromAppBase(resolvedBasePath);
|
|
64
86
|
if (frameworkRoutes && typeof frameworkRoutes.registerRoutes === 'function') {
|
|
@@ -82,6 +104,7 @@ export const registerMasterRoutes = async (resolvedBasePath, router) => {
|
|
|
82
104
|
if (!isCloudflare) {
|
|
83
105
|
await registerAppRoutes(resolvedBasePath, router);
|
|
84
106
|
}
|
|
107
|
+
await registerManifestRoutes(router);
|
|
85
108
|
if (router.routes.length === 0) {
|
|
86
109
|
await registerFrameworkRoutes(resolvedBasePath, router);
|
|
87
110
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-manifest.d.ts","sourceRoot":"","sources":["../../../src/bootstrap/service-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,oBAAoB,CAAM,CAAC;AAEvE,eAAe,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitContainerCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/InitContainerCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"InitContainerCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/InitContainerCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAyKlE,eAAO,MAAM,oBAAoB;cACrB,YAAY;EAkBtB,CAAC"}
|
|
@@ -97,80 +97,21 @@ services:
|
|
|
97
97
|
- '7772:7772'
|
|
98
98
|
|
|
99
99
|
`;
|
|
100
|
-
const DOCKERFILE_TEMPLATE = String.raw
|
|
101
|
-
# Build Stage - Compile TypeScript
|
|
102
|
-
FROM node:20-bookworm-slim AS builder
|
|
100
|
+
const DOCKERFILE_TEMPLATE = String.raw `FROM zintrust/zintrust:latest AS runtime
|
|
103
101
|
|
|
104
102
|
WORKDIR /app
|
|
105
103
|
|
|
106
|
-
# Reuse npm cache across builds (requires BuildKit)
|
|
107
|
-
ENV NPM_CONFIG_CACHE=/root/.npm
|
|
108
|
-
ENV NPM_CONFIG_PREFER_OFFLINE=true
|
|
109
|
-
|
|
110
|
-
# Install build dependencies for native modules (better-sqlite3, bcrypt)
|
|
111
|
-
RUN apt-get update \
|
|
112
|
-
&& apt-get install -y --no-install-recommends python3 make g++ \
|
|
113
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
114
|
-
|
|
115
|
-
# Copy package files
|
|
116
|
-
COPY package.json package-lock.json ./
|
|
117
|
-
|
|
118
|
-
# Install dependencies (including dev dependencies needed for build)
|
|
119
|
-
RUN --mount=type=cache,target=/root/.npm,id=zintrust-npm-cache,sharing=locked \
|
|
120
|
-
npm config set fetch-retries 5 \
|
|
121
|
-
&& npm config set fetch-retry-mintimeout 20000 \
|
|
122
|
-
&& npm config set fetch-retry-maxtimeout 120000 \
|
|
123
|
-
&& npm ci
|
|
124
|
-
|
|
125
|
-
# Copy source code using COPY . . to handle optional folders automatically
|
|
126
|
-
COPY . .
|
|
127
|
-
|
|
128
|
-
# Build TypeScript to JavaScript
|
|
129
|
-
ARG BUILD_VARIANT=full
|
|
130
|
-
RUN --mount=type=cache,target=/root/.npm,id=zintrust-npm-cache,sharing=locked npm run build:dk
|
|
131
|
-
|
|
132
|
-
# Runtime Stage - Production image
|
|
133
|
-
FROM node:20-bookworm-slim AS runtime
|
|
134
|
-
|
|
135
|
-
WORKDIR /app
|
|
136
|
-
|
|
137
|
-
# Set environment variables
|
|
138
104
|
ENV NODE_ENV=production
|
|
139
105
|
ENV PORT=7772
|
|
140
106
|
ENV HOST=0.0.0.0
|
|
141
107
|
|
|
142
|
-
# Create non-root user for security
|
|
143
|
-
RUN groupadd -g 1001 nodejs && useradd -u 1001 -g 1001 -m -s /usr/sbin/nologin nodejs
|
|
144
|
-
|
|
145
|
-
# Copy package files for production dependencies
|
|
146
|
-
COPY package.json package-lock.json ./
|
|
147
|
-
|
|
148
|
-
# Install only production dependencies (requires build tools for native modules)
|
|
149
|
-
RUN --mount=type=cache,target=/root/.npm,id=zintrust-npm-cache,sharing=locked \
|
|
150
|
-
apt-get update \
|
|
151
|
-
&& apt-get install -y --no-install-recommends python3 make g++ \
|
|
152
|
-
&& npm ci --omit=dev \
|
|
153
|
-
&& apt-get purge -y --auto-remove python3 make g++ \
|
|
154
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
155
|
-
|
|
156
|
-
# Copy compiled code from builder stage
|
|
157
|
-
COPY --from=builder /app/dist ./dist
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# Change ownership to nodejs user
|
|
161
|
-
RUN chown -R nodejs:nodejs /app
|
|
162
|
-
|
|
163
|
-
# Switch to non-root user
|
|
164
108
|
USER nodejs
|
|
165
109
|
|
|
166
|
-
# Health check
|
|
167
110
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
168
111
|
CMD node -e "require('node:http').get('http://localhost:7772/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"
|
|
169
112
|
|
|
170
|
-
# Expose port
|
|
171
113
|
EXPOSE 7772
|
|
172
114
|
|
|
173
|
-
# Start application (compiled JS; no tsx needed in runtime)
|
|
174
115
|
CMD ["node", "dist/src/boot/bootstrap.js"]
|
|
175
116
|
`;
|
|
176
117
|
const backupSuffix = () => new Date().toISOString().replaceAll(/[:.]/g, '-');
|
|
@@ -215,7 +215,7 @@ const warnIfAdapterMissing = (cmd, conn) => {
|
|
|
215
215
|
if (conn.driver === 'mysql' && DatabaseAdapterRegistry.get('mysql') === undefined) {
|
|
216
216
|
cmd.warn('MySQL adapter is not installed/registered; migrations may not hit a real MySQL DB.');
|
|
217
217
|
cmd.warn('Install via `zin plugin install adapter:mysql` (or `zin add db:mysql`).');
|
|
218
|
-
cmd.debug('[debug] Expected a side-effect import in src/zintrust.plugins.ts like: import "
|
|
218
|
+
cmd.debug('[debug] Expected a side-effect import in src/zintrust.plugins.ts like: import "../../../packages/db-mysql/src/register";');
|
|
219
219
|
}
|
|
220
220
|
if (conn.driver === 'postgresql' && DatabaseAdapterRegistry.get('postgresql') === undefined) {
|
|
221
221
|
cmd.warn('PostgreSQL adapter is not installed/registered; migrations may not hit a real PostgreSQL DB.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoutesCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/RoutesCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"RoutesCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/RoutesCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAuVvF,eAAO,MAAM,aAAa;cACd,YAAY;EAatB,CAAC;AAEH,eAAe,aAAa,CAAC"}
|
|
@@ -6,6 +6,8 @@ import { BaseCommand } from '../BaseCommand.js';
|
|
|
6
6
|
import { Env } from '../../config/env.js';
|
|
7
7
|
import { Router } from '../../routes/Router.js';
|
|
8
8
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
9
|
+
import { isObject } from '../../helper/index.js';
|
|
10
|
+
import { ProjectRuntime } from '../../runtime/ProjectRuntime.js';
|
|
9
11
|
const parseGroupBy = (value) => {
|
|
10
12
|
const raw = typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
11
13
|
if (raw === '' || raw === 'group')
|
|
@@ -157,6 +159,37 @@ const renderTable = (rows) => {
|
|
|
157
159
|
console.log(bottom);
|
|
158
160
|
/* eslint-enable no-console */
|
|
159
161
|
};
|
|
162
|
+
const annotateManifestRoutes = (router, beforeCount, serviceId) => {
|
|
163
|
+
const routes = Router.getRoutes(router);
|
|
164
|
+
for (const route of routes.slice(beforeCount)) {
|
|
165
|
+
route.__zintrustServiceId = serviceId;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const getRouteServiceId = (route) => {
|
|
169
|
+
return route.__zintrustServiceId ?? '';
|
|
170
|
+
};
|
|
171
|
+
const registerManifestRoutes = async (router) => {
|
|
172
|
+
await ProjectRuntime.tryLoadNodeRuntime();
|
|
173
|
+
const serviceManifest = ProjectRuntime.getServiceManifest();
|
|
174
|
+
if (serviceManifest.length === 0)
|
|
175
|
+
return;
|
|
176
|
+
for (const entry of serviceManifest) {
|
|
177
|
+
if (entry.monolithEnabled === false || typeof entry.loadRoutes !== 'function')
|
|
178
|
+
continue;
|
|
179
|
+
try {
|
|
180
|
+
const beforeCount = Router.getRoutes(router).length;
|
|
181
|
+
// eslint-disable-next-line no-await-in-loop
|
|
182
|
+
const mod = await entry.loadRoutes();
|
|
183
|
+
if (isObject(mod) && typeof mod.registerRoutes === 'function') {
|
|
184
|
+
mod.registerRoutes(router);
|
|
185
|
+
annotateManifestRoutes(router, beforeCount, entry.id);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Ignore broken optional service routes and keep listing what is available.
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
160
193
|
const buildRows = async (options) => {
|
|
161
194
|
const groupBy = parseGroupBy(options.groupBy);
|
|
162
195
|
const filterText = typeof options.filter === 'string' ? options.filter.trim().toLowerCase() : '';
|
|
@@ -174,12 +207,14 @@ const buildRows = async (options) => {
|
|
|
174
207
|
catch {
|
|
175
208
|
// routes/api.ts not found, continue with just core routes
|
|
176
209
|
}
|
|
210
|
+
await registerManifestRoutes(router);
|
|
177
211
|
const routes = Router.getRoutes(router);
|
|
178
212
|
const rows = routes.map((route) => {
|
|
179
213
|
const path = normalizePath(route.path);
|
|
214
|
+
const serviceId = getRouteServiceId(route);
|
|
180
215
|
let group = '';
|
|
181
216
|
if (groupBy === 'service') {
|
|
182
|
-
group = deriveService(path);
|
|
217
|
+
group = serviceId === '' ? deriveService(path) : serviceId;
|
|
183
218
|
}
|
|
184
219
|
else if (groupBy === 'group') {
|
|
185
220
|
group = deriveGroup(path);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA2sBvF,eAAO,MAAM,YAAY;cACb,YAAY;EA6BtB,CAAC"}
|
|
@@ -168,8 +168,19 @@ const resolveCacheEnabledPreference = (options) => {
|
|
|
168
168
|
return options.cache;
|
|
169
169
|
return undefined;
|
|
170
170
|
};
|
|
171
|
-
const
|
|
172
|
-
|
|
171
|
+
const findNearestPackageJsonDir = (cwd) => {
|
|
172
|
+
let current = path.resolve(cwd);
|
|
173
|
+
while (true) {
|
|
174
|
+
if (existsSync(path.join(current, 'package.json')))
|
|
175
|
+
return current;
|
|
176
|
+
const parent = path.dirname(current);
|
|
177
|
+
if (parent === current)
|
|
178
|
+
return undefined;
|
|
179
|
+
current = parent;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
const readPackageJsonFromDir = (dir) => {
|
|
183
|
+
const packagePath = path.join(dir, 'package.json');
|
|
173
184
|
if (!existsSync(packagePath)) {
|
|
174
185
|
throw ErrorFactory.createCliError("Error: No ZinTrust app found. Run 'zin new <project>' or ensure package.json exists.");
|
|
175
186
|
}
|
|
@@ -181,6 +192,24 @@ const readPackageJson = (cwd) => {
|
|
|
181
192
|
throw ErrorFactory.createTryCatchError('Failed to read package.json', error);
|
|
182
193
|
}
|
|
183
194
|
};
|
|
195
|
+
const resolveStartContext = (cwd) => {
|
|
196
|
+
const projectRoot = findNearestPackageJsonDir(cwd) ?? cwd;
|
|
197
|
+
const packageDir = findNearestPackageJsonDir(cwd);
|
|
198
|
+
return {
|
|
199
|
+
cwd,
|
|
200
|
+
projectRoot,
|
|
201
|
+
...(packageDir === undefined ? {} : { packageJson: readPackageJsonFromDir(packageDir) }),
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
const requirePackageJson = (context) => {
|
|
205
|
+
if (context.packageJson !== undefined)
|
|
206
|
+
return context.packageJson;
|
|
207
|
+
throw ErrorFactory.createCliError("Error: No ZinTrust app found. Run 'zin new <project>' or ensure package.json exists.");
|
|
208
|
+
};
|
|
209
|
+
const buildStartEnv = (projectRoot) => ({
|
|
210
|
+
...process.env,
|
|
211
|
+
ZINTRUST_PROJECT_ROOT: projectRoot,
|
|
212
|
+
});
|
|
184
213
|
const isFrameworkRepo = (packageJson) => packageJson.name === '@zintrust/core';
|
|
185
214
|
const hasDevScript = (packageJson) => {
|
|
186
215
|
const scripts = packageJson.scripts;
|
|
@@ -263,14 +292,14 @@ const resolveNodeProdCommand = (cwd) => {
|
|
|
263
292
|
}
|
|
264
293
|
return { command: 'node', args: [compiled] };
|
|
265
294
|
};
|
|
266
|
-
const executeWranglerStart = async (cmd,
|
|
295
|
+
const executeWranglerStart = async (cmd, context, port, runtime, envName, wranglerConfig) => {
|
|
267
296
|
if (runtime !== undefined) {
|
|
268
297
|
throw ErrorFactory.createCliError('Error: --runtime is not supported with --wrangler (Wrangler controls Workers runtime).');
|
|
269
298
|
}
|
|
270
299
|
const normalizedConfig = typeof wranglerConfig === 'string' ? wranglerConfig.trim() : '';
|
|
271
|
-
const explicitConfigFullPath = normalizedConfig.length > 0 ? path.join(cwd, normalizedConfig) : undefined;
|
|
272
|
-
const configPath = explicitConfigFullPath ?? findWranglerConfig(cwd);
|
|
273
|
-
const entry = resolveWranglerEntry(cwd);
|
|
300
|
+
const explicitConfigFullPath = normalizedConfig.length > 0 ? path.join(context.cwd, normalizedConfig) : undefined;
|
|
301
|
+
const configPath = explicitConfigFullPath ?? findWranglerConfig(context.cwd);
|
|
302
|
+
const entry = resolveWranglerEntry(context.cwd);
|
|
274
303
|
if (explicitConfigFullPath !== undefined) {
|
|
275
304
|
if (existsSync(explicitConfigFullPath)) {
|
|
276
305
|
// ok
|
|
@@ -300,7 +329,7 @@ const executeWranglerStart = async (cmd, cwd, port, runtime, envName, wranglerCo
|
|
|
300
329
|
const exitCode = await SpawnUtil.spawnAndWait({
|
|
301
330
|
command: 'wrangler',
|
|
302
331
|
args: wranglerArgs,
|
|
303
|
-
env:
|
|
332
|
+
env: buildStartEnv(context.projectRoot),
|
|
304
333
|
});
|
|
305
334
|
process.exit(exitCode);
|
|
306
335
|
};
|
|
@@ -321,92 +350,98 @@ const ensureTmpRunnerFile = (cwd, filename, content) => {
|
|
|
321
350
|
}
|
|
322
351
|
return fullPath;
|
|
323
352
|
};
|
|
324
|
-
const executeDenoStart = async (cmd,
|
|
353
|
+
const executeDenoStart = async (cmd, context, mode, watchEnabled, _port, runtime) => {
|
|
325
354
|
if (runtime !== undefined) {
|
|
326
355
|
throw ErrorFactory.createCliError('Error: --runtime cannot be used with --deno.');
|
|
327
356
|
}
|
|
328
357
|
if (mode === 'testing') {
|
|
329
358
|
throw ErrorFactory.createCliError('Error: Cannot start server in testing mode. Use development or production.');
|
|
330
359
|
}
|
|
331
|
-
const startModuleSpecifier = resolveRuntimeStartModuleSpecifier(cwd);
|
|
332
|
-
const denoRunner = ensureTmpRunnerFile(cwd, 'zin-start-deno.ts', createDenoRunnerSource(startModuleSpecifier));
|
|
360
|
+
const startModuleSpecifier = resolveRuntimeStartModuleSpecifier(context.cwd);
|
|
361
|
+
const denoRunner = ensureTmpRunnerFile(context.cwd, 'zin-start-deno.ts', createDenoRunnerSource(startModuleSpecifier));
|
|
333
362
|
const args = [];
|
|
334
363
|
if (mode === 'development' && watchEnabled)
|
|
335
364
|
args.push('watch');
|
|
336
365
|
args.push(denoRunner);
|
|
337
366
|
cmd.info('Starting in Deno adapter mode...');
|
|
338
|
-
const exitCode = await SpawnUtil.spawnAndWait({
|
|
367
|
+
const exitCode = await SpawnUtil.spawnAndWait({
|
|
368
|
+
command: 'tsx',
|
|
369
|
+
args,
|
|
370
|
+
env: buildStartEnv(context.projectRoot),
|
|
371
|
+
});
|
|
339
372
|
process.exit(exitCode);
|
|
340
373
|
};
|
|
341
|
-
const executeLambdaStart = async (cmd,
|
|
374
|
+
const executeLambdaStart = async (cmd, context, mode, watchEnabled, _port, runtime) => {
|
|
342
375
|
if (runtime !== undefined) {
|
|
343
376
|
throw ErrorFactory.createCliError('Error: --runtime cannot be used with --lambda.');
|
|
344
377
|
}
|
|
345
378
|
if (mode === 'testing') {
|
|
346
379
|
throw ErrorFactory.createCliError('Error: Cannot start server in testing mode. Use development or production.');
|
|
347
380
|
}
|
|
348
|
-
const startModuleSpecifier = resolveRuntimeStartModuleSpecifier(cwd);
|
|
349
|
-
const lambdaRunner = ensureTmpRunnerFile(cwd, 'zin-start-lambda.ts', createLambdaRunnerSource(startModuleSpecifier));
|
|
381
|
+
const startModuleSpecifier = resolveRuntimeStartModuleSpecifier(context.cwd);
|
|
382
|
+
const lambdaRunner = ensureTmpRunnerFile(context.cwd, 'zin-start-lambda.ts', createLambdaRunnerSource(startModuleSpecifier));
|
|
350
383
|
const args = [];
|
|
351
384
|
if (mode === 'development' && watchEnabled)
|
|
352
385
|
args.push('watch');
|
|
353
386
|
args.push(lambdaRunner);
|
|
354
387
|
cmd.info('Starting in Lambda adapter mode...');
|
|
355
|
-
const exitCode = await SpawnUtil.spawnAndWait({
|
|
388
|
+
const exitCode = await SpawnUtil.spawnAndWait({
|
|
389
|
+
command: 'tsx',
|
|
390
|
+
args,
|
|
391
|
+
env: buildStartEnv(context.projectRoot),
|
|
392
|
+
});
|
|
356
393
|
process.exit(exitCode);
|
|
357
394
|
};
|
|
358
|
-
const executeNodeStart = async (cmd,
|
|
395
|
+
const executeNodeStart = async (cmd, context, mode, watchEnabled, _port) => {
|
|
359
396
|
if (mode === 'testing') {
|
|
360
397
|
throw ErrorFactory.createCliError('Error: Cannot start server in testing mode. Use --force to override (not supported).');
|
|
361
398
|
}
|
|
362
399
|
if (mode === 'development') {
|
|
363
400
|
if (!watchEnabled) {
|
|
364
401
|
cmd.warn('Watch mode disabled; starting once.');
|
|
365
|
-
const bootstrap = resolveBootstrapEntryTs(cwd);
|
|
402
|
+
const bootstrap = resolveBootstrapEntryTs(context.cwd);
|
|
366
403
|
const args = bootstrap === undefined ? ['src/index.ts'] : [bootstrap];
|
|
367
404
|
const exitCode = await SpawnUtil.spawnAndWait({
|
|
368
405
|
command: 'tsx',
|
|
369
406
|
args,
|
|
370
407
|
forwardSignals: false,
|
|
371
|
-
env:
|
|
408
|
+
env: buildStartEnv(context.projectRoot),
|
|
372
409
|
});
|
|
373
410
|
process.exit(exitCode);
|
|
374
411
|
}
|
|
375
|
-
const
|
|
376
|
-
const dev = resolveNodeDevCommand(cwd, packageJson);
|
|
412
|
+
const dev = resolveNodeDevCommand(context.cwd, requirePackageJson(context));
|
|
377
413
|
cmd.info('Starting in development mode (watch enabled)...');
|
|
378
414
|
const exitCode = await SpawnUtil.spawnAndWait({
|
|
379
415
|
command: dev.command,
|
|
380
416
|
args: dev.args,
|
|
381
417
|
forwardSignals: false,
|
|
382
|
-
env:
|
|
418
|
+
env: buildStartEnv(context.projectRoot),
|
|
383
419
|
});
|
|
384
420
|
process.exit(exitCode);
|
|
385
421
|
}
|
|
386
|
-
const prod = resolveNodeProdCommand(cwd);
|
|
422
|
+
const prod = resolveNodeProdCommand(context.cwd);
|
|
387
423
|
cmd.info('Starting in production mode...');
|
|
388
424
|
const exitCode = await SpawnUtil.spawnAndWait({
|
|
389
425
|
command: prod.command,
|
|
390
426
|
args: prod.args,
|
|
391
427
|
forwardSignals: false,
|
|
392
|
-
env:
|
|
428
|
+
env: buildStartEnv(context.projectRoot),
|
|
393
429
|
});
|
|
394
430
|
process.exit(exitCode);
|
|
395
431
|
};
|
|
396
|
-
const executeSplitStart = async (cmd,
|
|
432
|
+
const executeSplitStart = async (cmd, context, _options) => {
|
|
397
433
|
cmd.info('🚀 Starting in split mode (Producer + Consumer)...');
|
|
398
|
-
const
|
|
399
|
-
const webDev = resolveNodeDevCommand(cwd, packageJson);
|
|
434
|
+
const webDev = resolveNodeDevCommand(context.cwd, requirePackageJson(context));
|
|
400
435
|
// Producer Environment
|
|
401
436
|
const producerEnv = {
|
|
402
|
-
...
|
|
437
|
+
...buildStartEnv(context.projectRoot),
|
|
403
438
|
WORKER_ENABLED: 'false',
|
|
404
439
|
QUEUE_ENABLED: 'true',
|
|
405
440
|
RUNTIME_MODE: 'node-server',
|
|
406
441
|
};
|
|
407
442
|
// Consumer Environment
|
|
408
443
|
const consumerEnv = {
|
|
409
|
-
...
|
|
444
|
+
...buildStartEnv(context.projectRoot),
|
|
410
445
|
WORKER_ENABLED: 'true',
|
|
411
446
|
QUEUE_ENABLED: 'true',
|
|
412
447
|
RUNTIME_MODE: 'containers',
|
|
@@ -417,10 +452,10 @@ const executeSplitStart = async (cmd, cwd, _options) => {
|
|
|
417
452
|
};
|
|
418
453
|
// Resolve Consumer Command (zintrust worker:start-all)
|
|
419
454
|
// We try to use tsx against the source bin if possible
|
|
420
|
-
const workerArgs = existsSync(path.join(
|
|
455
|
+
const workerArgs = existsSync(path.join(context.projectRoot, 'bin/zin.ts'))
|
|
421
456
|
? ['bin/zin.ts', 'worker:start-all']
|
|
422
457
|
: ['dist/bin/zin.js', 'worker:start-all'];
|
|
423
|
-
const workerCommand = existsSync(path.join(
|
|
458
|
+
const workerCommand = existsSync(path.join(context.projectRoot, 'bin/zin.ts')) ? 'tsx' : 'node';
|
|
424
459
|
cmd.info('-------------------------------------------');
|
|
425
460
|
cmd.info('🔹 [Producer] Web Server starting...');
|
|
426
461
|
cmd.info('🔸 [Consumer] Worker Process starting...');
|
|
@@ -428,12 +463,14 @@ const executeSplitStart = async (cmd, cwd, _options) => {
|
|
|
428
463
|
const pProducer = SpawnUtil.spawnAndWait({
|
|
429
464
|
command: webDev.command,
|
|
430
465
|
args: webDev.args,
|
|
466
|
+
cwd: context.cwd,
|
|
431
467
|
env: producerEnv,
|
|
432
468
|
forwardSignals: true,
|
|
433
469
|
});
|
|
434
470
|
const pConsumer = SpawnUtil.spawnAndWait({
|
|
435
471
|
command: workerCommand,
|
|
436
472
|
args: workerArgs,
|
|
473
|
+
cwd: context.projectRoot,
|
|
437
474
|
env: consumerEnv,
|
|
438
475
|
forwardSignals: true,
|
|
439
476
|
});
|
|
@@ -441,6 +478,7 @@ const executeSplitStart = async (cmd, cwd, _options) => {
|
|
|
441
478
|
};
|
|
442
479
|
const executeStart = async (options, cmd) => {
|
|
443
480
|
const cwd = process.cwd();
|
|
481
|
+
const context = resolveStartContext(cwd);
|
|
444
482
|
EnvFileLoader.ensureLoaded();
|
|
445
483
|
const mode = resolveMode(options);
|
|
446
484
|
const port = resolvePort(options);
|
|
@@ -454,7 +492,7 @@ const executeStart = async (options, cmd) => {
|
|
|
454
492
|
if (variant === 'lambda')
|
|
455
493
|
effectiveRuntime = 'lambda';
|
|
456
494
|
if (mode === 'split') {
|
|
457
|
-
await executeSplitStart(cmd,
|
|
495
|
+
await executeSplitStart(cmd, context, options);
|
|
458
496
|
return;
|
|
459
497
|
}
|
|
460
498
|
assertCompatibleStartVariant(variant, configuredRuntime);
|
|
@@ -469,7 +507,7 @@ const executeStart = async (options, cmd) => {
|
|
|
469
507
|
const wranglerConfig = typeof options.wranglerConfig === 'string' && options.wranglerConfig.trim() !== ''
|
|
470
508
|
? options.wranglerConfig.trim()
|
|
471
509
|
: undefined;
|
|
472
|
-
await executeWranglerStart(cmd,
|
|
510
|
+
await executeWranglerStart(cmd, context, port, runtime, envName === '' ? undefined : envName, wranglerConfig);
|
|
473
511
|
return;
|
|
474
512
|
}
|
|
475
513
|
if (envName !== '') {
|
|
@@ -477,14 +515,14 @@ const executeStart = async (options, cmd) => {
|
|
|
477
515
|
}
|
|
478
516
|
const watchEnabled = resolveWatchPreference(options, mode);
|
|
479
517
|
if (variant === 'deno') {
|
|
480
|
-
await executeDenoStart(cmd,
|
|
518
|
+
await executeDenoStart(cmd, context, mode, watchEnabled, port, runtime);
|
|
481
519
|
return;
|
|
482
520
|
}
|
|
483
521
|
if (variant === 'lambda') {
|
|
484
|
-
await executeLambdaStart(cmd,
|
|
522
|
+
await executeLambdaStart(cmd, context, mode, watchEnabled, port, runtime);
|
|
485
523
|
return;
|
|
486
524
|
}
|
|
487
|
-
await executeNodeStart(cmd,
|
|
525
|
+
await executeNodeStart(cmd, context, mode, watchEnabled, port);
|
|
488
526
|
};
|
|
489
527
|
export const StartCommand = Object.freeze({
|
|
490
528
|
create() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/RouteGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAuBD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAqB3F;AAED;;GAEG;AAEH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA4CnF;
|
|
1
|
+
{"version":3,"file":"RouteGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/RouteGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAuBD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAqB3F;AAED;;GAEG;AAEH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA4CnF;AA8LD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,eAAe,EAAE,CAsCpD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,eAAe,EAAE,CA6BjD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,eAAe,EAAE,CA+BlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,EAAE,CAEhD;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;EAOzB,CAAC"}
|
|
@@ -115,7 +115,9 @@ ${routeRegistration}
|
|
|
115
115
|
* Build import statements
|
|
116
116
|
*/
|
|
117
117
|
function buildImports(options) {
|
|
118
|
-
const imports = [
|
|
118
|
+
const imports = [
|
|
119
|
+
"import { Router, type IRequest, type IResponse, type IRouter } from '../../index.js';",
|
|
120
|
+
];
|
|
119
121
|
// Collect unique controllers
|
|
120
122
|
const controllers = new Set();
|
|
121
123
|
for (const route of options.routes) {
|
|
@@ -208,7 +210,7 @@ function buildMethodRoute(route, router, groupMiddlewareList) {
|
|
|
208
210
|
const middlewareProp = buildMiddlewareProp(route, groupMiddlewareList);
|
|
209
211
|
const metaProp = `meta: { summary: ${escapeUnsafeChars(JSON.stringify(summary))}, tags: [${escapeUnsafeChars(JSON.stringify(tag))}] }`;
|
|
210
212
|
const options = `{ ${[middlewareProp, metaProp].filter((v) => v !== '').join(', ')} }`;
|
|
211
|
-
return ` Router.${method}(${router}, '${routePath}', (req, res) => ${controllerVar}.${action}(req, res), ${options});\n`;
|
|
213
|
+
return ` Router.${method}(${router}, '${routePath}', (req: IRequest, res: IResponse) => ${controllerVar}.${action}(req, res), ${options});\n`;
|
|
212
214
|
}
|
|
213
215
|
/**
|
|
214
216
|
* Build resource route (RESTful CRUD)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ServiceScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"ServiceScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ServiceScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD;;GAEG;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuB7F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAGnF;AAED;;GAEG;AAEH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC,CAiDhC;AA8bD,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAC"}
|