@produtype/core 1.2.0 → 1.4.0
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
CHANGED
|
@@ -191,7 +191,7 @@ prodkit plan ../my-app --output prodkit-plan.md
|
|
|
191
191
|
|
|
192
192
|
_Generated from the analyzer itself — run `npm run docs:stacks` after changing a detector._
|
|
193
193
|
|
|
194
|
-
- **Backend:** Express, Next.js, NestJS, Fastify, Hono, Elysia, Koa, AdonisJS, SvelteKit, Remix, Nuxt, Nitro, Astro, Django, Flask, FastAPI, aiohttp, Litestar, Sanic, Tornado, Starlette, Streamlit, Gradio, Dash, Chainlit, Gin, Echo, Fiber, chi, Gorilla, Beego, Go, Axum, Actix Web, Rocket, Warp, Tide, Poem, Salvo, Tower HTTP, Hyper, Spring Boot, Quarkus, Micronaut, Ktor, Javalin, Vert.x, Dropwizard, Helidon, Rails, Sinatra, Hanami, Roda, Grape, Ruby, Laravel, Symfony, Slim, CodeIgniter, CakePHP, Yii, PHP, ASP.NET Core,
|
|
194
|
+
- **Backend:** Express, Next.js, NestJS, Fastify, Hono, Elysia, Koa, AdonisJS, SvelteKit, Remix, Nuxt, Nitro, Astro, Django, Flask, FastAPI, aiohttp, Litestar, Sanic, Tornado, Starlette, Streamlit, Gradio, Dash, Chainlit, Gin, Echo, Fiber, chi, Gorilla, Beego, Go, Axum, Actix Web, Rocket, Warp, Tide, Poem, Salvo, Tower HTTP, Hyper, Spring Boot, Quarkus, Micronaut, Ktor, Javalin, Vert.x, Dropwizard, Helidon, Rails, Sinatra, Hanami, Roda, Grape, Ruby, Laravel, Symfony, Slim, CodeIgniter, CakePHP, Yii, PHP, ASP.NET Core, Cloudflare Workers
|
|
195
195
|
- **Frontend:** React, Vite, Vue, Nuxt, Svelte, Angular, Astro, Solid, Qwik, Preact, Remix, htmx, Tailwind CSS, Electron
|
|
196
196
|
- **Mobile:** Flutter, React Native, iOS (native), Android (native), SwiftUI, UIKit, Jetpack Compose, Android views
|
|
197
197
|
- **Databases:** Postgres, MySQL, SQLite, SQL Server, MongoDB, Redis, Firestore, DynamoDB, Convex
|
|
@@ -210,7 +210,7 @@ How some of these are decided:
|
|
|
210
210
|
- **Ruby** — a Gemfile with no web framework in it
|
|
211
211
|
- **PHP** — PHP sources with no framework in composer.json
|
|
212
212
|
- **ASP.NET Core** — the Microsoft.NET.Sdk.Web SDK attribute
|
|
213
|
-
-
|
|
213
|
+
- **Cloudflare Workers** — a wrangler manifest beside a module exporting a fetch handler
|
|
214
214
|
- **Flutter** — pubspec.yaml — classified as a client application, not a backend
|
|
215
215
|
- **React Native** — the react-native or expo dependency
|
|
216
216
|
- **iOS (native)** — Info.plist, Package.swift, a Podfile or an .xcodeproj in the tree
|
|
@@ -245,6 +245,7 @@ const LABELS = {
|
|
|
245
245
|
electron: 'Electron',
|
|
246
246
|
flutter: 'Flutter',
|
|
247
247
|
'react-native': 'React Native',
|
|
248
|
+
'cloudflare workers': 'Cloudflare Workers',
|
|
248
249
|
ios: 'iOS (native)',
|
|
249
250
|
android: 'Android (native)',
|
|
250
251
|
swiftui: 'SwiftUI',
|
|
@@ -348,7 +349,11 @@ function supportedStacks() {
|
|
|
348
349
|
...entries(exports.PHP_BACKEND_FRAMEWORKS.map(([id]) => id)),
|
|
349
350
|
{ id: 'php', label: 'PHP', detectedFrom: 'PHP sources with no framework in composer.json' },
|
|
350
351
|
{ id: 'aspnet-core', label: 'ASP.NET Core', detectedFrom: 'the Microsoft.NET.Sdk.Web SDK attribute' },
|
|
351
|
-
{
|
|
352
|
+
{
|
|
353
|
+
id: 'cloudflare workers',
|
|
354
|
+
label: 'Cloudflare Workers',
|
|
355
|
+
detectedFrom: 'a wrangler manifest beside a module exporting a fetch handler',
|
|
356
|
+
},
|
|
352
357
|
],
|
|
353
358
|
frontend: [
|
|
354
359
|
{ id: 'react', label: 'React' },
|
|
@@ -227,6 +227,34 @@ async function detectBackend(ctx) {
|
|
|
227
227
|
* in the package manager, and "this is a .NET project" was never an answer to
|
|
228
228
|
* "what serves the requests".
|
|
229
229
|
*/
|
|
230
|
+
/**
|
|
231
|
+
* A Cloudflare Worker, which is a server with no server framework in it.
|
|
232
|
+
*
|
|
233
|
+
* `wrangler.toml` names the entry module and the compatibility date; the module
|
|
234
|
+
* exports an object with a `fetch` handler. That pair is Cloudflare's documented
|
|
235
|
+
* contract and there is no other way to write a Worker — but together they were read
|
|
236
|
+
* as nothing at all: no backend, no stack, and a report that declined to score.
|
|
237
|
+
*
|
|
238
|
+
* Both halves are required. A `wrangler.toml` beside a static site deploys Pages and
|
|
239
|
+
* serves no requests of its own, and an `export default { fetch }` with no manifest
|
|
240
|
+
* is a module somebody may import.
|
|
241
|
+
*
|
|
242
|
+
* Weaker than the rest of this file, and worth saying: the shape was diagnosed on a
|
|
243
|
+
* case built from Cloudflare's documentation rather than found in a repository. Every
|
|
244
|
+
* other rule here has a named project behind it. A real Worker should confirm this
|
|
245
|
+
* one.
|
|
246
|
+
*/
|
|
247
|
+
const wranglerManifests = ctx.files.all.filter((f) => /(^|\/)wrangler\.(toml|jsonc?)$/.test(f));
|
|
248
|
+
if (wranglerManifests.length > 0 && !frameworks.includes('hono')) {
|
|
249
|
+
const fetchHandler = await (0, textSearch_1.searchInFiles)(ctx.root, ctx.files.source, [/export\s+default\s*\{[\s\S]{0,120}?\bfetch\s*\(/, /^\s*async\s+fetch\s*\(\s*request/m], 2);
|
|
250
|
+
if (fetchHandler.length > 0) {
|
|
251
|
+
frameworks.push('cloudflare workers');
|
|
252
|
+
evidence.push({ type: 'file', value: wranglerManifests[0], file: wranglerManifests[0] });
|
|
253
|
+
for (const hit of fetchHandler.slice(0, 1)) {
|
|
254
|
+
evidence.push({ type: 'snippet', value: hit.snippet, file: hit.file, line: hit.line });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
230
258
|
/**
|
|
231
259
|
* Astro, which is a backend only when it is configured to be one.
|
|
232
260
|
*
|
|
@@ -268,10 +268,33 @@ async function detectPackaging(ctx) {
|
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
const tauriConfigs = all.filter((file) => /(^|\/)tauri\.conf\.json$/.test(file));
|
|
271
|
+
/**
|
|
272
|
+
* A browser extension, which ships inside a packaged archive like any other bundle.
|
|
273
|
+
*
|
|
274
|
+
* `manifest_version` is the key the WebExtensions platform requires, and it appears
|
|
275
|
+
* in nothing else. The file it sits in is not always `manifest.json`: Dark Reader
|
|
276
|
+
* keeps one per browser — `manifest-chrome-mv3.json`, `manifest-firefox.json` —
|
|
277
|
+
* and Violentmonkey writes `manifest.yml` and compiles it at build time. The key is
|
|
278
|
+
* the contract; the file name is the project's business.
|
|
279
|
+
*
|
|
280
|
+
* Violentmonkey was asked at `high` how it delivers assets over HTTP. Its assets are
|
|
281
|
+
* inside the `.xpi` the browser installed, which is the Electron case again.
|
|
282
|
+
*/
|
|
283
|
+
const extensionManifests = [];
|
|
284
|
+
for (const file of all.filter((f) => /(^|\/)manifest[\w.-]*\.(json|yml|yaml)$/i.test(f)).slice(0, 8)) {
|
|
285
|
+
const raw = (await (0, readTextFileSafe_1.readTextFileSafe)(ctx.root, file)) ?? '';
|
|
286
|
+
if (/["']?manifest_version["']?\s*[:=]/.test(raw))
|
|
287
|
+
extensionManifests.push(file);
|
|
288
|
+
}
|
|
271
289
|
const desktopBundle = [
|
|
272
290
|
...(0, detectContext_1.hasAnyDep)(ctx, ['electron', 'electron-builder', '@tauri-apps/api', '@tauri-apps/cli'])
|
|
273
291
|
.map((dep) => ({ type: 'dependency', value: dep })),
|
|
274
292
|
...tauriConfigs.slice(0, 2).map((file) => ({ type: 'file', value: file, file })),
|
|
293
|
+
...extensionManifests.slice(0, 2).map((file) => ({
|
|
294
|
+
type: 'file',
|
|
295
|
+
value: `${file} declares manifest_version`,
|
|
296
|
+
file,
|
|
297
|
+
})),
|
|
275
298
|
];
|
|
276
299
|
const entrypointCount = nodeEntrypoints.length
|
|
277
300
|
+ (pythonEntrypoints ? 1 : 0)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@produtype/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|