@corva/create-app 0.0.0-210a1a8
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/README.md +220 -0
- package/bin/cca.js +5 -0
- package/bin/create-corva-app.cjs +25 -0
- package/common/node/.env +15 -0
- package/common/node/.env.sample +26 -0
- package/common/node/gitignore +130 -0
- package/common/package.json +3 -0
- package/common/python/.env +5 -0
- package/common/python/.env.sample +7 -0
- package/common/python/Makefile +18 -0
- package/common/python/gitignore +161 -0
- package/common/python/pyproject.toml +25 -0
- package/common/python/uv.lock +381 -0
- package/common/ui/config/vite/corva-vite-config.mjs +384 -0
- package/common/ui/devApp.js +1 -0
- package/common/ui/index.html +17 -0
- package/common/ui/isolatedApp.js +1 -0
- package/common/ui/public/DevCenterIsolatedAppPage.html +26 -0
- package/common/ui/public/favicon.ico +0 -0
- package/common/ui/vite.config.mjs +3 -0
- package/common/ui/vitest.global-setup.js +4 -0
- package/common/ui/vitest.setup.js +26 -0
- package/lib/commands/attach.js +28 -0
- package/lib/commands/create.js +471 -0
- package/lib/commands/release.js +73 -0
- package/lib/commands/rerun.js +34 -0
- package/lib/commands/zip.js +39 -0
- package/lib/constants/cache.js +5 -0
- package/lib/constants/cli.js +32 -0
- package/lib/constants/manifest.js +263 -0
- package/lib/constants/messages.js +15 -0
- package/lib/constants/package.js +300 -0
- package/lib/flow.js +59 -0
- package/lib/flows/attach.js +8 -0
- package/lib/flows/lib/api.js +385 -0
- package/lib/flows/lib/create-zip-archive.js +83 -0
- package/lib/flows/lib/json.js +30 -0
- package/lib/flows/lib/manifest.js +81 -0
- package/lib/flows/lib/notification.js +142 -0
- package/lib/flows/lib/step-error.js +10 -0
- package/lib/flows/lib/waitForMs.js +3 -0
- package/lib/flows/prepare.js +6 -0
- package/lib/flows/release.js +30 -0
- package/lib/flows/rerun.js +8 -0
- package/lib/flows/steps/attach/add-app-to-stream.js +23 -0
- package/lib/flows/steps/attach/get-all-live-assets.js +135 -0
- package/lib/flows/steps/attach/index.js +5 -0
- package/lib/flows/steps/attach/prepare-data.js +19 -0
- package/lib/flows/steps/prepare-load-app-files.js +12 -0
- package/lib/flows/steps/release/add-label.js +10 -0
- package/lib/flows/steps/release/add-notes.js +10 -0
- package/lib/flows/steps/release/get-config.js +41 -0
- package/lib/flows/steps/release/prepare-data.js +12 -0
- package/lib/flows/steps/release/publish.js +11 -0
- package/lib/flows/steps/release/remove-failed-upload.js +21 -0
- package/lib/flows/steps/release/resolve-prebuilt-zip.js +35 -0
- package/lib/flows/steps/release/upload-zip-to-corva.js +136 -0
- package/lib/flows/steps/release/wait-for-build.js +36 -0
- package/lib/flows/steps/rerun/create-task.js +77 -0
- package/lib/flows/steps/rerun/ensure-that-app-in-stream.js +68 -0
- package/lib/flows/steps/rerun/get-app-version.js +111 -0
- package/lib/flows/steps/rerun/prepare-data.js +162 -0
- package/lib/flows/steps/rerun/prepare-well-and-stream-data.js +188 -0
- package/lib/flows/steps/rerun/rerun.js +13 -0
- package/lib/flows/steps/zip-cleanup.js +17 -0
- package/lib/flows/steps/zip-create-archive.js +15 -0
- package/lib/flows/steps/zip-file-list-resolve.js +273 -0
- package/lib/flows/steps/zip-prepare.js +20 -0
- package/lib/flows/steps/zip.js +6 -0
- package/lib/flows/zip-simple.js +8 -0
- package/lib/flows/zip.js +7 -0
- package/lib/helpers/cli-version.js +163 -0
- package/lib/helpers/commands.js +13 -0
- package/lib/helpers/logger.js +35 -0
- package/lib/helpers/manifest.js +82 -0
- package/lib/helpers/resolve-app-runtime.js +143 -0
- package/lib/helpers/utils.js +101 -0
- package/lib/helpers/versioning.js +94 -0
- package/lib/main.js +63 -0
- package/lib/options/api-key.js +6 -0
- package/lib/options/app-key.js +6 -0
- package/lib/options/app-version.js +3 -0
- package/lib/options/bump-version.js +19 -0
- package/lib/options/cache.js +11 -0
- package/lib/options/env.js +3 -0
- package/lib/options/original-cwd.js +3 -0
- package/lib/options/silent.js +3 -0
- package/lib/options/zip-file-name.js +18 -0
- package/package.json +1 -0
- package/template_extensions/corva/.commitlintrc.json +6 -0
- package/template_extensions/corva/.eslintrc +32 -0
- package/template_extensions/corva/.github/pull_request_template.md +14 -0
- package/template_extensions/corva/.github/workflows/code-checks.yml +15 -0
- package/template_extensions/corva/.github/workflows/develop.yml +19 -0
- package/template_extensions/corva/.github/workflows/feat-fix-delete.yml +14 -0
- package/template_extensions/corva/.github/workflows/feat-fix.yml +23 -0
- package/template_extensions/corva/.github/workflows/release-fix-X.X.X.yml +16 -0
- package/template_extensions/corva/.github/workflows/validate-pr-title.yml +19 -0
- package/template_extensions/corva/.husky/commit-msg +5 -0
- package/template_extensions/corva/.husky/pre-commit +4 -0
- package/template_extensions/corva/.release-please-manifest.json +3 -0
- package/template_extensions/corva/release-please-config.json +10 -0
- package/templates/scheduler_data-time/javascript/README.md +19 -0
- package/templates/scheduler_data-time/javascript/__tests__/processor.spec.js +15 -0
- package/templates/scheduler_data-time/javascript/index.js +15 -0
- package/templates/scheduler_data-time/python/README.md +31 -0
- package/templates/scheduler_data-time/python/lambda_function.py +7 -0
- package/templates/scheduler_data-time/python/test/__init__.py +0 -0
- package/templates/scheduler_data-time/python/test/app_test.py +10 -0
- package/templates/scheduler_data-time/typescript/README.md +25 -0
- package/templates/scheduler_data-time/typescript/__tests__/processor.spec.ts +15 -0
- package/templates/scheduler_data-time/typescript/index.ts +8 -0
- package/templates/scheduler_depth/javascript/README.md +19 -0
- package/templates/scheduler_depth/javascript/__tests__/processor.spec.js +17 -0
- package/templates/scheduler_depth/javascript/index.js +15 -0
- package/templates/scheduler_depth/python/README.md +31 -0
- package/templates/scheduler_depth/python/lambda_function.py +7 -0
- package/templates/scheduler_depth/python/test/__init__.py +0 -0
- package/templates/scheduler_depth/python/test/app_test.py +10 -0
- package/templates/scheduler_depth/typescript/README.md +25 -0
- package/templates/scheduler_depth/typescript/__tests__/processor.spec.ts +17 -0
- package/templates/scheduler_depth/typescript/index.ts +8 -0
- package/templates/scheduler_natural-time/javascript/README.md +19 -0
- package/templates/scheduler_natural-time/javascript/__tests__/processor.spec.js +15 -0
- package/templates/scheduler_natural-time/javascript/index.js +15 -0
- package/templates/scheduler_natural-time/python/README.md +31 -0
- package/templates/scheduler_natural-time/python/lambda_function.py +7 -0
- package/templates/scheduler_natural-time/python/test/__init__.py +0 -0
- package/templates/scheduler_natural-time/python/test/app_test.py +10 -0
- package/templates/scheduler_natural-time/typescript/README.md +25 -0
- package/templates/scheduler_natural-time/typescript/__tests__/processor.spec.ts +15 -0
- package/templates/scheduler_natural-time/typescript/index.ts +8 -0
- package/templates/stream_depth/javascript/README.md +19 -0
- package/templates/stream_depth/javascript/__tests__/processor.spec.js +20 -0
- package/templates/stream_depth/javascript/index.js +14 -0
- package/templates/stream_depth/python/README.md +31 -0
- package/templates/stream_depth/python/lambda_function.py +7 -0
- package/templates/stream_depth/python/test/__init__.py +0 -0
- package/templates/stream_depth/python/test/app_test.py +16 -0
- package/templates/stream_depth/typescript/README.md +25 -0
- package/templates/stream_depth/typescript/__tests__/processor.spec.ts +20 -0
- package/templates/stream_depth/typescript/index.ts +8 -0
- package/templates/stream_time/javascript/README.md +19 -0
- package/templates/stream_time/javascript/__tests__/processor.spec.js +14 -0
- package/templates/stream_time/javascript/index.js +14 -0
- package/templates/stream_time/python/README.md +31 -0
- package/templates/stream_time/python/lambda_function.py +7 -0
- package/templates/stream_time/python/test/__init__.py +0 -0
- package/templates/stream_time/python/test/app_test.py +16 -0
- package/templates/stream_time/typescript/README.md +25 -0
- package/templates/stream_time/typescript/__tests__/processor.spec.ts +14 -0
- package/templates/stream_time/typescript/index.ts +8 -0
- package/templates/task/javascript/README.md +19 -0
- package/templates/task/javascript/__tests__/processor.spec.js +16 -0
- package/templates/task/javascript/index.js +15 -0
- package/templates/task/python/README.md +31 -0
- package/templates/task/python/lambda_function.py +7 -0
- package/templates/task/python/test/__init__.py +0 -0
- package/templates/task/python/test/app_test.py +8 -0
- package/templates/task/typescript/README.md +25 -0
- package/templates/task/typescript/__tests__/processor.spec.ts +16 -0
- package/templates/task/typescript/index.ts +8 -0
- package/templates/ui/javascript/.codex/config.toml +3 -0
- package/templates/ui/javascript/.cursor/mcp.json +8 -0
- package/templates/ui/javascript/.eslintrc +13 -0
- package/templates/ui/javascript/.mcp.json +8 -0
- package/templates/ui/javascript/.prettierrc +1 -0
- package/templates/ui/javascript/AGENTS.md +306 -0
- package/templates/ui/javascript/CLAUDE.md +1 -0
- package/templates/ui/javascript/README.md +31 -0
- package/templates/ui/javascript/gitignore +27 -0
- package/templates/ui/javascript/src/App.completion.jsx +52 -0
- package/templates/ui/javascript/src/App.drilling.jsx +49 -0
- package/templates/ui/javascript/src/App.module.scss +17 -0
- package/templates/ui/javascript/src/AppSettings.jsx +28 -0
- package/templates/ui/javascript/src/__tests__/App.test.jsx +26 -0
- package/templates/ui/javascript/src/__tests__/AppSettings.test.jsx +28 -0
- package/templates/ui/javascript/src/__tests__/TestsExample.test.jsx +37 -0
- package/templates/ui/javascript/src/assets/logo.svg +7 -0
- package/templates/ui/javascript/src/constants.js +3 -0
- package/templates/ui/javascript/src/index.js +8 -0
- package/templates/ui/typescript/.codex/config.toml +3 -0
- package/templates/ui/typescript/.cursor/mcp.json +8 -0
- package/templates/ui/typescript/.eslintrc +31 -0
- package/templates/ui/typescript/.mcp.json +8 -0
- package/templates/ui/typescript/.prettierrc +1 -0
- package/templates/ui/typescript/AGENTS.md +347 -0
- package/templates/ui/typescript/CLAUDE.md +1 -0
- package/templates/ui/typescript/README.md +31 -0
- package/templates/ui/typescript/gitignore +27 -0
- package/templates/ui/typescript/src/App.completion.tsx +52 -0
- package/templates/ui/typescript/src/App.drilling.tsx +49 -0
- package/templates/ui/typescript/src/App.module.scss +17 -0
- package/templates/ui/typescript/src/AppSettings.tsx +28 -0
- package/templates/ui/typescript/src/__mocks__/mockData.ts +22 -0
- package/templates/ui/typescript/src/__tests__/App.test.tsx +27 -0
- package/templates/ui/typescript/src/__tests__/AppSettings.test.tsx +28 -0
- package/templates/ui/typescript/src/__tests__/TestsExample.test.tsx +37 -0
- package/templates/ui/typescript/src/assets/logo.svg +7 -0
- package/templates/ui/typescript/src/constants.ts +3 -0
- package/templates/ui/typescript/src/custom.d.ts +19 -0
- package/templates/ui/typescript/src/index.js +8 -0
- package/templates/ui/typescript/src/types.ts +3 -0
- package/templates/ui/typescript/tsconfig.json +20 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
// Ported from corva-monorepo-frontend tools/vite-config. Moves to
|
|
2
|
+
// @corva/dc-platform-shared once the standalone flow is proven, which is why
|
|
3
|
+
// nothing here imports from the app's own source.
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { join, resolve } from 'node:path';
|
|
7
|
+
|
|
8
|
+
import dotenv from 'dotenv';
|
|
9
|
+
import { expand } from 'dotenv-expand';
|
|
10
|
+
import react from '@vitejs/plugin-react';
|
|
11
|
+
import license from 'rollup-plugin-license';
|
|
12
|
+
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
|
13
|
+
import presetEnv from 'postcss-preset-env';
|
|
14
|
+
import { defineConfig } from 'vitest/config';
|
|
15
|
+
|
|
16
|
+
const require = createRequire(import.meta.url);
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
CORVA_API_ENVS,
|
|
20
|
+
CORVA_API_ENV_VARIABLES,
|
|
21
|
+
CORVA_GLOBAL_DEPENDENCIES,
|
|
22
|
+
} = require('@corva/dc-platform-shared/cjs/devcenter/webpack/constants.js');
|
|
23
|
+
const validateDependencies = require('@corva/dc-platform-shared/cjs/devcenter/webpack/validators/index.js');
|
|
24
|
+
const { updateDotEnv } = require('@corva/dc-platform-shared/cjs/devcenter/webpack/utils/serializeDotEnv.js');
|
|
25
|
+
|
|
26
|
+
const PLATFORM_SHARED_DIR = join(
|
|
27
|
+
require.resolve('@corva/dc-platform-shared/package.json'),
|
|
28
|
+
'..',
|
|
29
|
+
);
|
|
30
|
+
// NOTE: These imports are always bundled, never taken from the platform globals
|
|
31
|
+
const SKIP_IN_EXTERNALS = ['react/jsx-runtime', 'highcharts/'];
|
|
32
|
+
|
|
33
|
+
const isLegalIdentifier = value => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value);
|
|
34
|
+
|
|
35
|
+
const toLegalIdentifier = value => {
|
|
36
|
+
const identifier = value.replace(/[^A-Za-z0-9_$]/g, '_');
|
|
37
|
+
|
|
38
|
+
return isLegalIdentifier(identifier) ? identifier : `_${identifier}`;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const toGlobalSegmentAccess = segment =>
|
|
42
|
+
/^\d+$/.test(segment) ? `[${segment}]` : `[${JSON.stringify(segment)}]`;
|
|
43
|
+
|
|
44
|
+
const getSegmentedGlobalAssignmentPrefix = appIdentifier => {
|
|
45
|
+
const [rootSegment, ...segments] = appIdentifier.split('.');
|
|
46
|
+
const rootAccessor = `this[${JSON.stringify(rootSegment)}]`;
|
|
47
|
+
|
|
48
|
+
if (segments.length === 0) {
|
|
49
|
+
return `${rootAccessor}=`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let currentAccessor = rootAccessor;
|
|
53
|
+
const initializers = [`${rootAccessor}=${rootAccessor}||{}`];
|
|
54
|
+
|
|
55
|
+
segments.slice(0, -1).forEach(segment => {
|
|
56
|
+
currentAccessor += toGlobalSegmentAccess(segment);
|
|
57
|
+
initializers.push(`${currentAccessor}=${currentAccessor}||{}`);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
currentAccessor += toGlobalSegmentAccess(segments[segments.length - 1]);
|
|
61
|
+
|
|
62
|
+
return `${initializers.join(',')},${currentAccessor}=`;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const getGlobalAssignmentPrefixes = globalName =>
|
|
66
|
+
[
|
|
67
|
+
...new Set([
|
|
68
|
+
isLegalIdentifier(globalName) ? `var ${globalName}=` : '',
|
|
69
|
+
isLegalIdentifier(globalName)
|
|
70
|
+
? `this.${globalName}=`
|
|
71
|
+
: `this[${JSON.stringify(globalName)}]=`,
|
|
72
|
+
`this[${JSON.stringify(globalName)}]=`,
|
|
73
|
+
getSegmentedGlobalAssignmentPrefix(globalName),
|
|
74
|
+
]),
|
|
75
|
+
].filter(Boolean);
|
|
76
|
+
|
|
77
|
+
const normalizeIifeGlobalAssignment = (jsContent, appIdentifier, emittedGlobalName) => {
|
|
78
|
+
const normalizedAssignment = `this[${JSON.stringify(appIdentifier)}]=`;
|
|
79
|
+
|
|
80
|
+
if (jsContent.includes(normalizedAssignment)) {
|
|
81
|
+
return jsContent;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const assignmentPrefix = getGlobalAssignmentPrefixes(emittedGlobalName).find(prefix =>
|
|
85
|
+
jsContent.includes(prefix),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if (assignmentPrefix) {
|
|
89
|
+
return jsContent.replace(assignmentPrefix, normalizedAssignment);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Rolldown doesn't emit a global assignment for IIFE output — inject one.
|
|
93
|
+
// Terser rewrites `(function(){})()` → `!function(){}()` when the result is discarded.
|
|
94
|
+
// Replacing `!` with the assignment (`this["name"]=function(){}()`) is valid JS
|
|
95
|
+
// because after `=` the `function` keyword is an expression, not a declaration.
|
|
96
|
+
if (jsContent.trimStart().startsWith('!function')) {
|
|
97
|
+
return jsContent.replace('!function', `${normalizedAssignment}function`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return normalizedAssignment + jsContent;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const createCssInjection = cssContent =>
|
|
104
|
+
`(function(){var s=document.createElement('style');s.textContent=${JSON.stringify(
|
|
105
|
+
cssContent,
|
|
106
|
+
)};document.head.appendChild(s)})();`;
|
|
107
|
+
|
|
108
|
+
// The platform loads a single file, so the emitted stylesheets are folded back into it.
|
|
109
|
+
const finalizeJsBundle = ({ outDir, cssFileNames, appIdentifier, emittedGlobalName }) => {
|
|
110
|
+
const jsPath = join(outDir, 'app.js');
|
|
111
|
+
const css = cssFileNames
|
|
112
|
+
.map(fileName => readFileSync(join(outDir, fileName), 'utf-8'))
|
|
113
|
+
.join('');
|
|
114
|
+
const jsContent = readFileSync(jsPath, 'utf-8');
|
|
115
|
+
|
|
116
|
+
writeFileSync(
|
|
117
|
+
jsPath,
|
|
118
|
+
normalizeIifeGlobalAssignment(
|
|
119
|
+
css ? createCssInjection(css) + jsContent : jsContent,
|
|
120
|
+
appIdentifier,
|
|
121
|
+
emittedGlobalName,
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
cssFileNames.forEach(fileName => unlinkSync(join(outDir, fileName)));
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const getCorvaApiEnvVariables = () => {
|
|
129
|
+
const apiEnv = process.env.CORVA_API_ENV || CORVA_API_ENVS.production;
|
|
130
|
+
|
|
131
|
+
if (apiEnv in CORVA_API_ENVS) {
|
|
132
|
+
return CORVA_API_ENV_VARIABLES[apiEnv];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
console.error(`CORVA_API_ENV should be one of [${Object.keys(CORVA_API_ENVS).join(', ')}]`);
|
|
136
|
+
|
|
137
|
+
return process.exit(1);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// webpack's dev config added this entry point whenever the app depends on
|
|
141
|
+
// mapbox-gl: it reads the access token off @corva/ui and publishes the
|
|
142
|
+
// configured instance as window['mapbox-gl'].
|
|
143
|
+
// A virtual module rather than a direct node_modules URL: mapbox-gl's dist is
|
|
144
|
+
// CJS, so it only imports cleanly once Vite's resolver and dep optimizer see it.
|
|
145
|
+
const MAPBOX_DEV_SETUP_ID = 'virtual:corva-mapbox-dev-setup';
|
|
146
|
+
|
|
147
|
+
const mapboxDevSetupPlugin = () => ({
|
|
148
|
+
name: 'corva-mapbox-dev-setup',
|
|
149
|
+
resolveId(id) {
|
|
150
|
+
return id === MAPBOX_DEV_SETUP_ID ? `\0${MAPBOX_DEV_SETUP_ID}` : null;
|
|
151
|
+
},
|
|
152
|
+
load(id) {
|
|
153
|
+
return id === `\0${MAPBOX_DEV_SETUP_ID}`
|
|
154
|
+
? "import '@corva/dc-platform-shared/cjs/devcenter/webpack/MapboxGlDevSetupEntryPoint.js';"
|
|
155
|
+
: null;
|
|
156
|
+
},
|
|
157
|
+
transformIndexHtml: () => [
|
|
158
|
+
{
|
|
159
|
+
tag: 'script',
|
|
160
|
+
attrs: { type: 'module', src: `/@id/__x00__${MAPBOX_DEV_SETUP_ID}` },
|
|
161
|
+
injectTo: 'body',
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// The DevCenter dev page edits the app's .env through this endpoint.
|
|
167
|
+
const dotEnvEndpointPlugin = appDirectory => ({
|
|
168
|
+
name: 'corva-dotenv-endpoint',
|
|
169
|
+
configureServer(server) {
|
|
170
|
+
server.middlewares.use('/dotenv', (req, res, next) => {
|
|
171
|
+
if (req.method !== 'PATCH') {
|
|
172
|
+
return next();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const envPath = resolve(appDirectory, '.env');
|
|
176
|
+
const chunks = [];
|
|
177
|
+
|
|
178
|
+
req.on('data', chunk => chunks.push(chunk));
|
|
179
|
+
req.on('end', () => {
|
|
180
|
+
const currentEnv = existsSync(envPath) ? readFileSync(envPath, 'utf-8') : '';
|
|
181
|
+
|
|
182
|
+
writeFileSync(envPath, updateDotEnv(currentEnv, JSON.parse(Buffer.concat(chunks))));
|
|
183
|
+
res.statusCode = 200;
|
|
184
|
+
res.end();
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
export const createViteConfig = ({ pwd }) => {
|
|
191
|
+
expand(dotenv.config({ path: resolve(pwd, '.env'), quiet: true }));
|
|
192
|
+
|
|
193
|
+
const packageJson = JSON.parse(readFileSync(resolve(pwd, 'package.json'), 'utf-8'));
|
|
194
|
+
const manifestJson = JSON.parse(readFileSync(resolve(pwd, 'manifest.json'), 'utf-8'));
|
|
195
|
+
|
|
196
|
+
const appKey = manifestJson.application.key;
|
|
197
|
+
const version = packageJson.version;
|
|
198
|
+
const appIdentifier = `${appKey.replace(/\./g, '_')}-${version}`;
|
|
199
|
+
const appIifeName = toLegalIdentifier(appIdentifier);
|
|
200
|
+
|
|
201
|
+
const globalDependencies = Object.keys(CORVA_GLOBAL_DEPENDENCIES);
|
|
202
|
+
const externalPatterns = globalDependencies.map(
|
|
203
|
+
libName => new RegExp(`(^${libName}$|^${libName}/)([^]+)?`),
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const isExternal = source =>
|
|
207
|
+
!SKIP_IN_EXTERNALS.some(skipped => source.startsWith(skipped)) &&
|
|
208
|
+
externalPatterns.some(pattern => pattern.test(source));
|
|
209
|
+
|
|
210
|
+
// Package names are not valid JS identifiers, so every global is read off `this`.
|
|
211
|
+
const toGlobal = id => {
|
|
212
|
+
const staticGlobal = globalDependencies.find(libName => libName === id);
|
|
213
|
+
|
|
214
|
+
if (staticGlobal) {
|
|
215
|
+
return `this["${staticGlobal}"].default || this["${staticGlobal}"]`;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const dep = globalDependencies.find(libName => id.startsWith(libName));
|
|
219
|
+
|
|
220
|
+
if (!dep) {
|
|
221
|
+
throw new Error(`Unknown dependency: ${id}`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return `this["${dep}"]${id.replace(dep, '').replace(/\//g, '.')}`;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const getAlias = () => {
|
|
228
|
+
// jest resolved '~' to src for both templates; keep it in the build too
|
|
229
|
+
const defaultAlias = { '~': resolve(pwd, 'src') };
|
|
230
|
+
const tsconfigPath = resolve(pwd, 'tsconfig.json');
|
|
231
|
+
|
|
232
|
+
if (!existsSync(tsconfigPath)) {
|
|
233
|
+
return defaultAlias;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const { compilerOptions } = JSON.parse(readFileSync(tsconfigPath, 'utf-8'));
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
...defaultAlias,
|
|
240
|
+
...Object.fromEntries(
|
|
241
|
+
Object.entries(compilerOptions?.paths || {}).map(([key, [value]]) => [
|
|
242
|
+
key.replace('/*', ''),
|
|
243
|
+
resolve(pwd, value.replace('/*', '')),
|
|
244
|
+
]),
|
|
245
|
+
),
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
return defineConfig(({ command }) => {
|
|
250
|
+
validateDependencies({ packageJson });
|
|
251
|
+
|
|
252
|
+
const config = {
|
|
253
|
+
root: pwd,
|
|
254
|
+
server: {
|
|
255
|
+
host: process.env.HOST || 'app.local.corva.ai',
|
|
256
|
+
port: Number(process.env.PORT) || 8080,
|
|
257
|
+
},
|
|
258
|
+
css: {
|
|
259
|
+
modules: { localsConvention: 'camelCase' },
|
|
260
|
+
postcss: { plugins: [presetEnv({ stage: 3 })] },
|
|
261
|
+
},
|
|
262
|
+
plugins: [react(), dotEnvEndpointPlugin(pwd)],
|
|
263
|
+
resolve: { alias: getAlias() },
|
|
264
|
+
test: {
|
|
265
|
+
watch: false,
|
|
266
|
+
globals: true,
|
|
267
|
+
environment: 'jsdom',
|
|
268
|
+
setupFiles: ['./vitest.setup.js'],
|
|
269
|
+
globalSetup: ['./vitest.global-setup.js'],
|
|
270
|
+
coverage: {
|
|
271
|
+
provider: 'v8',
|
|
272
|
+
include: ['src/**/*.{js,jsx,ts,tsx}'],
|
|
273
|
+
thresholds: { branches: 60, functions: 60, lines: 60, statements: 60 },
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
if (command === 'serve') {
|
|
279
|
+
return {
|
|
280
|
+
...config,
|
|
281
|
+
define: {
|
|
282
|
+
global: {},
|
|
283
|
+
// Webpack's EnvironmentPlugin exposed the whole environment, so apps read
|
|
284
|
+
// their own REACT_APP_* vars straight off process.env.
|
|
285
|
+
'process.env': {
|
|
286
|
+
...process.env,
|
|
287
|
+
DEV_CENTER_APP_PATH: '',
|
|
288
|
+
NODE_ENV: 'development',
|
|
289
|
+
REACT_APP_ENVIRONMENT: process.env.REACT_APP_ENVIRONMENT || 'development',
|
|
290
|
+
...getCorvaApiEnvVariables(),
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
plugins: [
|
|
294
|
+
...config.plugins,
|
|
295
|
+
...(packageJson.dependencies?.['mapbox-gl'] ? [mapboxDevSetupPlugin()] : []),
|
|
296
|
+
viteStaticCopy({
|
|
297
|
+
watch: { reloadPageOnChange: false },
|
|
298
|
+
targets: [
|
|
299
|
+
{ src: `${PLATFORM_SHARED_DIR}/assets/*`, dest: 'static/media' },
|
|
300
|
+
{
|
|
301
|
+
src: `${join(PLATFORM_SHARED_DIR, '../ui/assets')}/*`,
|
|
302
|
+
dest: 'static/media',
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
}),
|
|
306
|
+
],
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
...config,
|
|
312
|
+
define: {
|
|
313
|
+
'process.env': { NODE_ENV: 'production' },
|
|
314
|
+
'process.env.NODE_ENV': '"production"',
|
|
315
|
+
},
|
|
316
|
+
plugins: [
|
|
317
|
+
...config.plugins,
|
|
318
|
+
viteStaticCopy({ targets: [{ src: 'manifest.json', dest: '.' }] }),
|
|
319
|
+
{
|
|
320
|
+
name: 'corva-single-file-bundle',
|
|
321
|
+
writeBundle(_options, bundle) {
|
|
322
|
+
finalizeJsBundle({
|
|
323
|
+
outDir: resolve(pwd, 'dist'),
|
|
324
|
+
cssFileNames: Object.keys(bundle).filter(fileName => fileName.endsWith('.css')),
|
|
325
|
+
appIdentifier,
|
|
326
|
+
emittedGlobalName: appIifeName,
|
|
327
|
+
});
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
build: {
|
|
332
|
+
outDir: 'dist',
|
|
333
|
+
emptyOutDir: true,
|
|
334
|
+
copyPublicDir: false,
|
|
335
|
+
sourcemap: false,
|
|
336
|
+
cssCodeSplit: false,
|
|
337
|
+
minify: 'terser',
|
|
338
|
+
terserOptions: {
|
|
339
|
+
compress: { drop_console: true, drop_debugger: true },
|
|
340
|
+
format: { comments: false },
|
|
341
|
+
},
|
|
342
|
+
// lib mode plus named exports keeps the IIFE compatible with the platform
|
|
343
|
+
// loader, which reads `this["appKey-version"].default.component`.
|
|
344
|
+
lib: {
|
|
345
|
+
entry: resolve(pwd, 'src/index.js'),
|
|
346
|
+
name: appIifeName,
|
|
347
|
+
fileName: () => 'app.js',
|
|
348
|
+
formats: ['iife'],
|
|
349
|
+
},
|
|
350
|
+
rolldownOptions: {
|
|
351
|
+
external: isExternal,
|
|
352
|
+
moduleTypes: { '.cjs': 'js' },
|
|
353
|
+
output: {
|
|
354
|
+
format: 'iife',
|
|
355
|
+
name: appIifeName,
|
|
356
|
+
entryFileNames: 'app.js',
|
|
357
|
+
globals: toGlobal,
|
|
358
|
+
exports: 'named',
|
|
359
|
+
// Rolldown doesn't rewrite `require()` inside bundled CJS modules (e.g.
|
|
360
|
+
// react-is) to their external global references. This shim resolves them
|
|
361
|
+
// to the globals the IIFE receives as params.
|
|
362
|
+
intro:
|
|
363
|
+
'var require=function(id){var g=globalThis[id];return g&&g.default||g;};',
|
|
364
|
+
},
|
|
365
|
+
plugins: [
|
|
366
|
+
{
|
|
367
|
+
// Rolldown rejects `typeof require` as a define key (not an identifier),
|
|
368
|
+
// so the CJS-detection branches are stripped by transform instead.
|
|
369
|
+
name: 'replace-typeof-require',
|
|
370
|
+
transform(code) {
|
|
371
|
+
if (!code.includes('typeof require')) return null;
|
|
372
|
+
|
|
373
|
+
return { code: code.replaceAll('typeof require', '"undefined"'), map: null };
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
license({
|
|
377
|
+
thirdParty: { output: resolve(pwd, 'dist/app.js.LICENSE.txt') },
|
|
378
|
+
}),
|
|
379
|
+
],
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
});
|
|
384
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@corva/dc-platform-shared/cjs/devcenter/webpack/DevServerEntryPoint.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<link rel="icon" href="/favicon.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
<meta name="theme-color" content="#000000" />
|
|
8
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" />
|
|
9
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
|
10
|
+
<title>Corva React App</title>
|
|
11
|
+
</head>
|
|
12
|
+
<body data-corva-theme-dark>
|
|
13
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
14
|
+
<div id="root"></div>
|
|
15
|
+
<script type="module" src="/devApp.js"></script>
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@corva/dc-platform-shared/cjs/devcenter/webpack/DevServerIsolatedAppEntryPoint.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<link rel="icon" href="/favicon.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
<meta name="theme-color" content="#000000" />
|
|
8
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" />
|
|
9
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
|
10
|
+
<title>Corva React App</title>
|
|
11
|
+
</head>
|
|
12
|
+
<body data-corva-theme-dark>
|
|
13
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
14
|
+
<div id="root"></div>
|
|
15
|
+
<!-- Vite only injects the react-refresh preamble into index.html, so this page installs it itself. -->
|
|
16
|
+
<script type="module">
|
|
17
|
+
import RefreshRuntime from '/@react-refresh';
|
|
18
|
+
|
|
19
|
+
RefreshRuntime.injectIntoGlobalHook(window);
|
|
20
|
+
window.$RefreshReg$ = () => {};
|
|
21
|
+
window.$RefreshSig$ = () => type => type;
|
|
22
|
+
window.__vite_plugin_react_preamble_installed__ = true;
|
|
23
|
+
</script>
|
|
24
|
+
<script type="module" src="/isolatedApp.js"></script>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import '@testing-library/jest-dom/vitest';
|
|
4
|
+
|
|
5
|
+
class FakeObserver {
|
|
6
|
+
observe() {}
|
|
7
|
+
|
|
8
|
+
unobserve() {}
|
|
9
|
+
|
|
10
|
+
disconnect() {}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
vi.stubGlobal('ResizeObserver', FakeObserver);
|
|
14
|
+
vi.stubGlobal('MutationObserver', FakeObserver);
|
|
15
|
+
|
|
16
|
+
// jsdom 22 cannot parse the container queries @corva/ui's components inject, and
|
|
17
|
+
// reports that straight to stderr on every import. Drop those lines only.
|
|
18
|
+
const writeToStderr = process.stderr.write.bind(process.stderr);
|
|
19
|
+
|
|
20
|
+
process.stderr.write = (chunk, ...rest) => {
|
|
21
|
+
if (String(chunk).includes('Could not parse CSS stylesheet')) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return writeToStderr(chunk, ...rest);
|
|
26
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { ERROR_ICON } from '../constants/messages.js';
|
|
4
|
+
import { runFlow } from '../flow.js';
|
|
5
|
+
import { ATTACH_FLOW } from '../flows/attach.js';
|
|
6
|
+
import { getRealWorkingDir } from '../helpers/commands.js';
|
|
7
|
+
import { apiKeyOption } from '../options/api-key.js';
|
|
8
|
+
import { appVersion } from '../options/app-version.js';
|
|
9
|
+
import { envOption } from '../options/env.js';
|
|
10
|
+
import { originalCwdOption } from '../options/original-cwd.js';
|
|
11
|
+
import { silentOption } from '../options/silent.js';
|
|
12
|
+
|
|
13
|
+
export const attachCommand = new Command('attach')
|
|
14
|
+
.description('Add app to live assets streams')
|
|
15
|
+
.argument('<project-directory>', 'Project directory to work with')
|
|
16
|
+
.addOption(apiKeyOption)
|
|
17
|
+
.addOption(envOption)
|
|
18
|
+
.addOption(silentOption)
|
|
19
|
+
.addOption(appVersion)
|
|
20
|
+
.addOption(originalCwdOption)
|
|
21
|
+
.action(async (dirName, options) => {
|
|
22
|
+
await runFlow(ATTACH_FLOW, { dirName: getRealWorkingDir(dirName, options), options });
|
|
23
|
+
})
|
|
24
|
+
.showHelpAfterError()
|
|
25
|
+
.showSuggestionAfterError(true)
|
|
26
|
+
.configureOutput({
|
|
27
|
+
outputError: (str, write) => write(chalk.red(`${ERROR_ICON} ${str}`)),
|
|
28
|
+
});
|