├── .changeset ├── README.md └── config.json ├── .dmno ├── config.mts └── tsconfig.json ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── config │ └── labeler.yaml └── workflows │ ├── pr-labeler.yaml │ ├── release-preview.yaml │ ├── release.yaml │ └── test.yaml ├── .gitignore ├── .nvmrc ├── .vscode ├── extensions.json └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── example-repo ├── .dmno │ ├── config.mts │ ├── custom-types.mts │ ├── prod.vault.json │ ├── tsconfig.json │ └── workspace.yaml ├── .gitignore ├── .nvmrc ├── dmno-env.d.ts ├── package.json ├── packages │ ├── api │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ ├── .env │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── package.json │ │ ├── src │ │ │ ├── custom-state.ts │ │ │ ├── dmno-env.d.ts │ │ │ ├── global.d.ts │ │ │ ├── lib │ │ │ │ ├── api-error.ts │ │ │ │ ├── cache.ts │ │ │ │ ├── client-ip.ts │ │ │ │ ├── defer-promise.ts │ │ │ │ ├── jwt.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── querystring.ts │ │ │ │ ├── redis.ts │ │ │ │ ├── request-logger.ts │ │ │ │ ├── this-file-path.ts │ │ │ │ ├── tracker.ts │ │ │ │ ├── try-catch.ts │ │ │ │ └── validation-helpers.ts │ │ │ ├── main.ts │ │ │ ├── routes │ │ │ │ └── index.ts │ │ │ └── scripts │ │ │ │ └── check-env.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── astro-web │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ ├── .env.sample │ │ ├── .gitignore │ │ ├── .vscode │ │ │ ├── extensions.json │ │ │ └── launch.json │ │ ├── README.md │ │ ├── astro.config.ts │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── favicon.svg │ │ ├── src │ │ │ ├── components │ │ │ │ ├── ClientVueConfigTest.vue │ │ │ │ ├── ConfigTest.astro │ │ │ │ └── ServerVueConfigTest.vue │ │ │ ├── dmno-env.d.ts │ │ │ ├── dmno-vue.d.ts │ │ │ ├── env.d.ts │ │ │ ├── layouts │ │ │ │ └── Layout.astro │ │ │ ├── pages │ │ │ │ ├── api.json.ts │ │ │ │ ├── index.astro │ │ │ │ ├── intercept-test.astro │ │ │ │ ├── intercept-test.json.ts │ │ │ │ ├── mdx-test.mdx │ │ │ │ ├── middleware-test.astro │ │ │ │ └── middleware-test.json.ts │ │ │ └── vue-app-config.ts │ │ └── tsconfig.json │ ├── dmno-ui-demo │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ └── package.json │ ├── express-js │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ ├── dmno-env.d.ts │ │ ├── main.js │ │ └── package.json │ ├── fastify │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ ├── package.json │ │ ├── src │ │ │ ├── dmno-env.d.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── group1 │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ └── package.json │ ├── nextjs-web │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ ├── .eslintrc.json │ │ ├── .gitignore │ │ ├── README.md │ │ ├── next.config.mjs │ │ ├── package.json │ │ ├── postcss.config.mjs │ │ ├── public │ │ │ ├── next.svg │ │ │ └── vercel.svg │ │ ├── src │ │ │ ├── app │ │ │ │ ├── api │ │ │ │ │ └── fetch-dynamic-public-config │ │ │ │ │ │ └── route.ts │ │ │ │ ├── app │ │ │ │ │ ├── api-edge │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── api-node │ │ │ │ │ │ └── route.ts │ │ │ │ │ ├── client-page │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── intercept-allow │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── intercept │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── leak-client │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── page-edge │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── page-node │ │ │ │ │ │ └── page.tsx │ │ │ │ │ └── server-action │ │ │ │ │ │ ├── action.ts │ │ │ │ │ │ └── page.tsx │ │ │ │ ├── favicon.ico │ │ │ │ ├── globals.css │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ ├── dmno-env.d.ts │ │ │ └── pages │ │ │ │ ├── api │ │ │ │ ├── api-edge.ts │ │ │ │ ├── api-node.ts │ │ │ │ └── fetch-dynamic-public-config2.ts │ │ │ │ └── pages │ │ │ │ ├── amp.tsx │ │ │ │ ├── page-edge.tsx │ │ │ │ └── page-node.tsx │ │ ├── tailwind.config.ts │ │ └── tsconfig.json │ ├── nuxt-web │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app.vue │ │ ├── dmno-env.d.ts │ │ ├── nuxt.config.ts │ │ ├── package.json │ │ ├── public │ │ │ └── favicon.ico │ │ ├── server │ │ │ ├── test.ts │ │ │ └── tsconfig.json │ │ └── tsconfig.json │ ├── remix-basic │ │ ├── .dmno │ │ │ ├── config.mts │ │ │ └── tsconfig.json │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── entry.client.tsx │ │ │ ├── entry.server.tsx │ │ │ ├── root.tsx │ │ │ ├── routes │ │ │ │ ├── _index.tsx │ │ │ │ ├── api.ts │ │ │ │ ├── intercept.tsx │ │ │ │ ├── leak.tsx │ │ │ │ └── server.tsx │ │ │ └── tailwind.css │ │ ├── dmno-env.d.ts │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── public │ │ │ └── favicon.ico │ │ ├── tailwind.config.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ └── webapp │ │ ├── .dmno │ │ ├── config.mts │ │ └── tsconfig.json │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── .vscode │ │ └── extensions.json │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ └── vite.svg │ │ ├── src │ │ ├── App.vue │ │ ├── dmno-env.d.ts │ │ ├── dmno-vue.d.ts │ │ ├── main.ts │ │ ├── style.css │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── vite.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── turbo.json ├── package.json ├── packages ├── chat.dmno.dev │ ├── README.md │ ├── _redirects │ └── index.html ├── configraph │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── caching.ts │ │ ├── common.ts │ │ ├── config-node.ts │ │ ├── data-types.ts │ │ ├── entity-template.ts │ │ ├── entity.ts │ │ ├── errors.ts │ │ ├── graph.ts │ │ ├── index.ts │ │ ├── pick.ts │ │ ├── plugin.ts │ │ ├── pretty-formatter.ts │ │ ├── resolvers.ts │ │ ├── resolvers │ │ │ ├── cache-resolver.ts │ │ │ ├── config-path.ts │ │ │ ├── injection.ts │ │ │ └── switch.ts │ │ ├── serialization-types.ts │ │ ├── type-generation.ts │ │ └── utils │ │ │ ├── graphlib-utils.ts │ │ │ ├── url-pattern-utils.test.ts │ │ │ └── url-pattern-utils.ts │ ├── test │ │ ├── array-type.test.ts │ │ ├── caching.test.ts │ │ ├── config-path-resolver.test.ts │ │ ├── data-types.test.ts │ │ ├── entity-template.test.ts │ │ ├── entity.test.ts │ │ ├── graph.test.ts │ │ ├── injection.test.ts │ │ ├── object-node.test.ts │ │ ├── pick.test.ts │ │ ├── resolution.test.ts │ │ └── switch-by-resolver.test.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ └── vite.config.mts ├── core │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── README.md │ ├── bin │ │ └── cli.js │ ├── dev-ui-dist │ ├── package.json │ ├── src │ │ ├── animation-test.ts │ │ ├── cli │ │ │ ├── cli-executable.ts │ │ │ ├── commands │ │ │ │ ├── clear-cache.command.ts │ │ │ │ ├── dev.command.ts │ │ │ │ ├── init.command.ts │ │ │ │ ├── plugin.command.ts │ │ │ │ ├── printenv.command.ts │ │ │ │ ├── resolve.command.ts │ │ │ │ ├── run.command.ts │ │ │ │ └── tapes │ │ │ │ │ ├── base.tape │ │ │ │ │ ├── clear-cache.tape │ │ │ │ │ ├── dev.tape │ │ │ │ │ ├── init.tape │ │ │ │ │ ├── plugin.tape │ │ │ │ │ ├── resolve.tape │ │ │ │ │ └── run.tape │ │ │ ├── lib │ │ │ │ ├── cache-helpers.ts │ │ │ │ ├── cli-ctx.ts │ │ │ │ ├── cli-error.ts │ │ │ │ ├── cli-schema-generation.ts │ │ │ │ ├── config-file-updater.test.ts │ │ │ │ ├── config-file-updater.ts │ │ │ │ ├── debug-timer.ts │ │ │ │ ├── diff-utils.ts │ │ │ │ ├── dmno-command.ts │ │ │ │ ├── env-file-helpers.test.ts │ │ │ │ ├── env-file-helpers.ts │ │ │ │ ├── formatting.ts │ │ │ │ ├── help-customizations.ts │ │ │ │ ├── init-helpers.ts │ │ │ │ ├── init-process.ts │ │ │ │ ├── loaders.ts │ │ │ │ ├── resolution-context-helpers.ts │ │ │ │ ├── schema-scaffold.ts │ │ │ │ ├── selection-helpers.ts │ │ │ │ ├── shell-helpers.test.ts │ │ │ │ ├── shell-helpers.ts │ │ │ │ ├── string-utils.ts │ │ │ │ ├── tsconfig-utils.ts │ │ │ │ └── watch-mode-helpers.ts │ │ │ └── plugin-cli-lib.ts │ │ ├── config-engine │ │ │ ├── authoring-utils.ts │ │ │ ├── check-errors-helpers.ts │ │ │ ├── config-engine.ts │ │ │ ├── configraph-adapter.ts │ │ │ ├── data-types.ts │ │ │ ├── dmno-configraph-cache.ts │ │ │ ├── dmno-plugin.ts │ │ │ ├── overrides.ts │ │ │ └── type-generation.ts │ │ ├── config-loader │ │ │ ├── config-loader.ts │ │ │ ├── dmno-server.ts │ │ │ ├── find-services.ts │ │ │ ├── serialization-types.ts │ │ │ └── vite-server.ts │ │ ├── external-types │ │ │ ├── esm-resolve.d.ts │ │ │ └── launch-editor.d.ts │ │ ├── globals-injector │ │ │ ├── auto-inject.ts │ │ │ └── injector.ts │ │ ├── index.ts │ │ ├── lib │ │ │ ├── async-utils.ts │ │ │ ├── certs.ts │ │ │ ├── constants.ts │ │ │ ├── delay.ts │ │ │ ├── detect-package-manager.ts │ │ │ ├── dotenv-utils.test.ts │ │ │ ├── dotenv-utils.ts │ │ │ ├── env-vars.ts │ │ │ ├── exec-helpers.ts │ │ │ ├── fs-utils.ts │ │ │ ├── git-utils.ts │ │ │ ├── http-interceptor-utils.ts │ │ │ ├── json-utils.ts │ │ │ ├── patch-response.ts │ │ │ ├── patch-server-response.ts │ │ │ ├── redaction-helpers.ts │ │ │ ├── this-file-path.ts │ │ │ ├── url-pattern-utils.test.ts │ │ │ ├── url-pattern-utils.ts │ │ │ └── web-server-utils.ts │ │ ├── utils.ts │ │ └── vendor-types │ │ │ ├── git.vendor-types.ts │ │ │ ├── index.ts │ │ │ └── postgres.vendor-types.ts │ ├── tsconfig.json │ ├── tsconfigs │ │ └── dmno-folder.json │ ├── tsup.config.ts │ ├── tsup.inject-standalone.config.ts │ └── vite.config.mts ├── dev-ui │ ├── .dmno │ │ ├── config.mts │ │ └── tsconfig.json │ ├── .eslintrc.cjs │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ ├── base.css │ │ │ └── main.css │ │ ├── components │ │ │ ├── _template.vue │ │ │ ├── general │ │ │ │ ├── DetailsTable │ │ │ │ │ ├── DetailsTable.vue │ │ │ │ │ └── DetailsTableRow.vue │ │ │ │ ├── Dropdown │ │ │ │ │ ├── DropdownMenu.vue │ │ │ │ │ └── DropdownMenuItem.vue │ │ │ │ ├── ErrorMessage.vue │ │ │ │ ├── Icon.vue │ │ │ │ ├── ScrollArea.vue │ │ │ │ ├── StyledValue.vue │ │ │ │ └── VButton.vue │ │ │ ├── graph │ │ │ │ ├── ConfigNode.vue │ │ │ │ ├── PluginLink.vue │ │ │ │ └── ServiceLink.vue │ │ │ ├── layout │ │ │ │ ├── HeaderBar.vue │ │ │ │ └── ThemeToggle.vue │ │ │ └── sidebar │ │ │ │ ├── GraphOutline.vue │ │ │ │ └── GraphOutlineItem.vue │ │ ├── dmno-env.d.ts │ │ ├── main.ts │ │ ├── store │ │ │ ├── index.ts │ │ │ ├── plugins │ │ │ │ └── pinia-hooks-plugin.ts │ │ │ ├── realtime.store.ts │ │ │ └── workspace.store.ts │ │ ├── utils │ │ │ ├── dom-utils.ts │ │ │ └── object-utils.ts │ │ └── views │ │ │ ├── ConfigOverview.vue │ │ │ ├── NotFoundPage.vue │ │ │ ├── PluginOverview.vue │ │ │ └── ServiceOverview.vue │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── dmno-api │ ├── .dmno │ │ ├── config.mts │ │ └── tsconfig.json │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── src │ │ ├── dmno-env.d.ts │ │ ├── hono-env.ts │ │ ├── lib │ │ │ ├── error-utils.ts │ │ │ └── mailerlite.ts │ │ ├── main.ts │ │ ├── routes │ │ │ └── signup.routes.ts │ │ └── types │ │ │ └── emailvalid.d.ts │ ├── tsconfig.json │ └── wrangler.json ├── docs-site │ ├── .dmno │ │ ├── config.mts │ │ └── tsconfig.json │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .vscode │ │ ├── extensions.json │ │ └── launch.json │ ├── CHANGELOG.md │ ├── README.md │ ├── astro.config.ts │ ├── package.json │ ├── postcss.config.cjs │ ├── public │ │ ├── _redirects │ │ ├── favicon.svg │ │ └── og-image.png │ ├── src │ │ ├── assets │ │ │ ├── blog │ │ │ │ ├── 1pass │ │ │ │ │ ├── dmno-1password.png │ │ │ │ │ ├── enable-cli.png │ │ │ │ │ └── env-blob.png │ │ │ │ └── screenshot-with-comments.png │ │ │ ├── docs-images │ │ │ │ ├── 1pass-demo.png │ │ │ │ ├── astro │ │ │ │ │ ├── leaked-secret-error.png │ │ │ │ │ ├── non-existant-error.png │ │ │ │ │ ├── non-existant-ts-error.png │ │ │ │ │ ├── non-public-error.png │ │ │ │ │ └── non-public-ts-error.png │ │ │ │ ├── console-redaction-demo.png │ │ │ │ ├── dynamic-schema-example.png │ │ │ │ ├── footer │ │ │ │ │ └── theophil.jpg │ │ │ │ ├── intellisense-demo.png │ │ │ │ ├── interceptor-demo.png │ │ │ │ ├── nextjs │ │ │ │ │ ├── intercept-error.png │ │ │ │ │ └── leak-error.png │ │ │ │ ├── pick-schema-example.png │ │ │ │ ├── platform-intellisense-example.png │ │ │ │ ├── plugins │ │ │ │ │ └── 1password │ │ │ │ │ │ └── blob-item-example.png │ │ │ │ ├── reuse-schema-example.png │ │ │ │ ├── security-demo.png │ │ │ │ └── validation-demo.png │ │ │ ├── domino-logo.svg │ │ │ ├── houston.webp │ │ │ ├── private-link.png │ │ │ ├── secret-ref.png │ │ │ ├── square-logo.svg │ │ │ └── tapes │ │ │ │ ├── clear-cache.gif │ │ │ │ ├── dev.gif │ │ │ │ ├── init.gif │ │ │ │ ├── load.gif │ │ │ │ ├── plugin.gif │ │ │ │ ├── resolve.gif │ │ │ │ └── run.gif │ │ ├── components │ │ │ ├── BugReportLink.astro │ │ │ ├── CTABlock.astro │ │ │ ├── CliCommand.astro │ │ │ ├── CustomStarlightBanner.astro │ │ │ ├── CustomStarlightFooter.astro │ │ │ ├── CustomStarlightHeader.astro │ │ │ ├── CustomStarlightMobileMenuFooter.astro │ │ │ ├── CustomStarlightPageTitle.astro │ │ │ ├── CustomStarlightThemeProvider.astro │ │ │ ├── DIcon.astro │ │ │ ├── DmnoExecPathAside.md │ │ │ ├── EmailSignup.vue │ │ │ ├── GA.astro │ │ │ ├── HeaderNav.astro │ │ │ ├── HeaderNavMarketing.astro │ │ │ ├── Hero.astro │ │ │ ├── LandingPageSection.astro │ │ │ ├── LogoBar.astro │ │ │ ├── PropTable.astro │ │ │ ├── SocialIcons.astro │ │ │ ├── TabbedCode.astro │ │ │ ├── TabbedTypeSettings.astro │ │ │ ├── ThemeSelect.vue │ │ │ ├── TileButton.vue │ │ │ ├── VideoBlock.astro │ │ │ ├── homepage │ │ │ │ ├── ConfigExample.astro │ │ │ │ ├── IntegrationTile.vue │ │ │ │ ├── IntegrationsHero.vue │ │ │ │ └── config-example.ts │ │ │ ├── layouts │ │ │ │ └── LandingPage.astro │ │ │ └── store.ts │ │ ├── content.config.ts │ │ ├── content │ │ │ └── docs │ │ │ │ ├── blog │ │ │ │ ├── dmno-astro-launch.md │ │ │ │ ├── dmno-nextjs-launch.md │ │ │ │ ├── hello-dmno.md │ │ │ │ └── safer-secrets-with-1pass.md │ │ │ │ └── docs │ │ │ │ ├── footer │ │ │ │ ├── about.mdx │ │ │ │ └── legal.md │ │ │ │ ├── get-started │ │ │ │ ├── concepts.md │ │ │ │ ├── quickstart.mdx │ │ │ │ ├── sample.mdx │ │ │ │ ├── security.mdx │ │ │ │ └── what-is-dmno.mdx │ │ │ │ ├── guides │ │ │ │ ├── custom-types.mdx │ │ │ │ ├── dynamic-config.mdx │ │ │ │ ├── env-files.mdx │ │ │ │ ├── incremental-adoption.mdx │ │ │ │ ├── monorepos.mdx │ │ │ │ ├── multi-env.mdx │ │ │ │ ├── overrides.mdx │ │ │ │ ├── schema.mdx │ │ │ │ ├── secret-segmentation.mdx │ │ │ │ └── typescript.mdx │ │ │ │ ├── integrations │ │ │ │ ├── astro.mdx │ │ │ │ ├── fastify.mdx │ │ │ │ ├── nextjs.mdx │ │ │ │ ├── node.mdx │ │ │ │ ├── overview.mdx │ │ │ │ ├── remix.mdx │ │ │ │ └── vite.mdx │ │ │ │ ├── platforms │ │ │ │ ├── cloudflare.mdx │ │ │ │ ├── github-actions.mdx │ │ │ │ ├── netlify.mdx │ │ │ │ ├── overview.mdx │ │ │ │ └── vercel.mdx │ │ │ │ ├── plugins │ │ │ │ ├── 1password.mdx │ │ │ │ ├── bitwarden.mdx │ │ │ │ ├── encrypted-vault.mdx │ │ │ │ ├── infisical.mdx │ │ │ │ └── overview.mdx │ │ │ │ └── reference │ │ │ │ ├── base-types.mdx │ │ │ │ ├── cli │ │ │ │ ├── clear-cache.mdx │ │ │ │ ├── commands.mdx │ │ │ │ ├── dev.mdx │ │ │ │ ├── init.mdx │ │ │ │ ├── plugin.mdx │ │ │ │ ├── resolve.mdx │ │ │ │ └── run.mdx │ │ │ │ ├── example.md │ │ │ │ └── helper-methods.mdx │ │ ├── dmno-env.d.ts │ │ ├── env.d.ts │ │ ├── pages │ │ │ ├── _drafts │ │ │ │ ├── docs-home.astro │ │ │ │ ├── integrations.astro │ │ │ │ ├── platforms.astro │ │ │ │ └── secrets.astro │ │ │ ├── docs │ │ │ │ └── index.astro │ │ │ └── index.astro │ │ ├── style │ │ │ ├── global.less │ │ │ └── reset.less │ │ └── utils │ │ │ ├── cli-plugin-vault.json │ │ │ ├── tapes.js │ │ │ └── typedoc │ │ │ ├── baseTypes.ts │ │ │ └── typedoc.json │ └── tsconfig.json ├── encryption-lib │ ├── .eslintrc.cjs │ ├── CHANGELOG.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── eslint-config │ ├── .eslintrc.base.cjs │ ├── .eslintrc.vue.cjs │ └── package.json ├── integrations │ ├── astro │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── dmno.meta.json │ │ ├── package.json │ │ ├── src │ │ │ ├── astro-middleware.ts │ │ │ ├── dev-toolbar-app.ts │ │ │ ├── fetch-public-dynamic-config.json.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── fastify │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── dmno.meta.json │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── nextjs │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── dmno.meta.json │ │ ├── package.json │ │ ├── src │ │ │ ├── index.ts │ │ │ └── inject-dmno-client.ts │ │ ├── tsconfig.json │ │ ├── tsup.config.bundled_q8a9iepgs4b.mjs │ │ └── tsup.config.ts │ ├── remix │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── dmno.meta.json │ │ ├── package.json │ │ ├── src │ │ │ ├── index.ts │ │ │ └── public-dynamic-config-api-route.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ └── vite │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── dmno.meta.json │ │ ├── package.json │ │ ├── src │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts ├── platforms │ ├── cloudflare │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── data-types.ts │ │ │ ├── dwrangler.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── netlify │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── build-plugin │ │ │ │ ├── index.ts │ │ │ │ └── manifest.yml │ │ │ ├── data-types.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ └── vercel │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ ├── data-types.ts │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts ├── plugins │ ├── 1password │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── cli-helper.ts │ │ │ ├── constants.ts │ │ │ ├── data-types.ts │ │ │ ├── index.ts │ │ │ ├── override-loader.ts │ │ │ └── plugin.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── bitwarden │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── constants.ts │ │ │ ├── data-types.ts │ │ │ ├── index.ts │ │ │ └── plugin.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ ├── encrypted-vault │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── cli │ │ │ │ ├── cli.ts │ │ │ │ ├── delete.command.ts │ │ │ │ ├── rotate-key.command.ts │ │ │ │ ├── setup.command.ts │ │ │ │ └── upsert.command.ts │ │ │ ├── data-types.ts │ │ │ ├── index.ts │ │ │ ├── lib │ │ │ │ ├── helpers.ts │ │ │ │ └── vault-file.ts │ │ │ └── plugin.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts │ └── infisical │ │ ├── .eslintrc.cjs │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ ├── constants.ts │ │ ├── data-types.ts │ │ ├── index.ts │ │ └── plugin.ts │ │ ├── tsconfig.json │ │ └── tsup.config.ts ├── ts-lib │ ├── .eslintrc.cjs │ ├── package.json │ ├── src │ │ ├── defer-promise.ts │ │ ├── index.ts │ │ ├── promise-delay.ts │ │ └── try-catch.ts │ └── tsconfig.json ├── tsconfig │ ├── package.json │ ├── tsconfig.browser.json │ └── tsconfig.node.json └── ui-lib │ ├── .eslintrc.cjs │ ├── package.json │ ├── src │ ├── brand-assets │ │ ├── domino-d-gradient-tile.svg │ │ ├── domino-d-gradient-tile@2x.png │ │ ├── domino-d-gradient.svg │ │ ├── domino-d-gradient@2x.png │ │ ├── domino-d-plain.svg │ │ ├── domino-d-plain@2x.png │ │ ├── domino-logo-full-outline.svg │ │ ├── domino-logo-full-white.svg │ │ ├── domino-logo-full.svg │ │ ├── domino-logo-only.svg │ │ └── domino-wordmark-only.svg │ ├── components │ │ ├── DmnoD.vue │ │ ├── DmnoTileLogo.vue │ │ └── DotsLoader.vue │ ├── index.ts │ └── style │ │ ├── base.css │ │ ├── utilities.css │ │ └── vars.css │ ├── tsconfig.json │ └── tsconfig.node.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts └── release-preview.js ├── tea.yaml └── turbo.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | 10 | ## Helpful commands: 11 | 12 | - `pnpm run changeset:add` - add a new changeset 13 | - `pnpm run changeset:version` - bundles all changesets into a single version 14 | - `pnpm run changeset:publish` - publish all changesets to npm 15 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 | "changelog": [ "@changesets/changelog-github", { "repo": "dmno-dev/dmno" } ], 4 | "commit": false, 5 | "fixed": [ ], 6 | "linked": [ ], 7 | "ignore": [ ], 8 | "access": "public", 9 | "baseBranch": "origin/main", 10 | "updateInternalDependencies": "patch", 11 | "privatePackages": { 12 | "version": false, 13 | "tag": false 14 | }, 15 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { 16 | "onlyUpdatePeerDependentsWhenOutOfRange": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | insert_final_newline = true 6 | end_of_line = lf 7 | indent_style = space 8 | indent_size = 2 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Discord Chat 4 | url: https://chat.dmno.dev 5 | about: Ask questions and discuss with other Vue users in real time. 6 | - name: LinkedIn 7 | url: https://www.linkedin.com/company/dmnodev/ 8 | about: Connect with the maintainers on LinkedIn. 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | *.ignore 4 | ignore 5 | 6 | .DS_Store 7 | 8 | config.local.ts 9 | .env.local 10 | .env.local.* 11 | 12 | .turbo 13 | 14 | vite.config.ts.timestamp* 15 | 16 | tmp-package-registry 17 | 18 | changesets-summary.json 19 | 20 | # DMNO files ### 21 | # local cache for resolved values 22 | **/.dmno/cache.json 23 | # encryption key used for cache 24 | **/.dmno/cache-key.json 25 | # generated type files 26 | **/.dmno/.typegen 27 | # iconify cache used in generated types 28 | **/.dmno/.icon-cache 29 | # local config overrides 30 | **/.dmno/.env.local 31 | # local ssl certs 32 | **/.dmno/certs 33 | 34 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22.14.0 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "pflannery.vscode-versionlens", 5 | "antfu.pnpm-catalog-lens", 6 | "unifiedjs.vscode-mdx", 7 | "allemandinstable.colorful-comments-refreshed", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 DMNO Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example-repo/.dmno/custom-types.mts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, createDmnoDataType } from "dmno"; 2 | 3 | export const GA4MeasurementId = createDmnoDataType({ 4 | typeLabel: 'ga/measurementId', 5 | extends: DmnoBaseTypes.string({ startsWith: 'G-', }), 6 | typeDescription: 'unique ID for a site registered in Google Analytics 4', 7 | externalDocs: { 8 | description: 'Google Analytics glossary', 9 | url: 'https://support.google.com/analytics/answer/12270356?hl=en', 10 | }, 11 | ui: { 12 | icon: 'bi:google', 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /example-repo/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/.dmno/workspace.yaml: -------------------------------------------------------------------------------- 1 | projects: 2 | # all packages in direct subdirs of packages/ 3 | - "packages/*" 4 | 5 | dev: 6 | host: dev.dmno.local 7 | ssl: true 8 | # port: 5666 9 | -------------------------------------------------------------------------------- /example-repo/.gitignore: -------------------------------------------------------------------------------- 1 | .vite-node 2 | 3 | # local cache for resolved values 4 | **/.dmno/cache.json 5 | # encryption key used for cache 6 | **/.dmno/cache-key.json 7 | # generated type files 8 | **/.dmno/.typegen 9 | # iconify cache used in generated types 10 | **/.dmno/.icon-cache 11 | # local ssl cert 12 | **/.dmno/certs 13 | -------------------------------------------------------------------------------- /example-repo/.nvmrc: -------------------------------------------------------------------------------- 1 | 20.11.1 2 | -------------------------------------------------------------------------------- /example-repo/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /example-repo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@example/monorepo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "author": "", 7 | "license": "MIT", 8 | "packageManager": "pnpm@9.15.4", 9 | "scripts": { 10 | "dmno:dev": "dmno dev" 11 | }, 12 | "devDependencies": { 13 | "@dmno/1password-plugin": "link:../packages/plugins/1password", 14 | "@dmno/bitwarden-plugin": "link:../packages/plugins/bitwarden", 15 | "@dmno/encrypted-vault-plugin": "link:../packages/plugins/encrypted-vault", 16 | "@dmno/infisical-plugin": "link:../packages/plugins/infisical", 17 | "dmno": "link:../packages/core" 18 | }, 19 | "dependencies": { 20 | "turbo": "^2.3.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example-repo/packages/api/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/api/.env: -------------------------------------------------------------------------------- 1 | # DEFAULT ENV VARS - DO NOT PUT ANYTHING SENSITIVE IN HERE!! 2 | 3 | # override locally in .env.local file 4 | # override on deployed environments via environment variables 5 | 6 | DEBUG='general,http' 7 | 8 | PORT=9001 9 | 10 | -------------------------------------------------------------------------------- /example-repo/packages/api/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | rules: { 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /example-repo/packages/api/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env.local 3 | dist 4 | *.ignore -------------------------------------------------------------------------------- /example-repo/packages/api/src/custom-state.ts: -------------------------------------------------------------------------------- 1 | import Router from '@koa/router'; 2 | import Koa from 'koa'; 3 | // import { UserWithTosStatus } from "./services/users.service"; 4 | 5 | // types for the things we add to our koa ctx 6 | export type CustomAppContext = { 7 | }; 8 | export type CustomAppState = { 9 | clientIp: string, 10 | // authUser?: UserWithTosStatus, 11 | }; 12 | 13 | export type CustomRouteContext = Koa.ParameterizedContext< 14 | CustomAppState, 15 | Router.RouterParamContext 16 | >; 17 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/global.d.ts: -------------------------------------------------------------------------------- 1 | type ISODateTimeString = string; 2 | type IpAddressString = string; 3 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/lib/client-ip.ts: -------------------------------------------------------------------------------- 1 | import requestIp from 'request-ip'; 2 | import Koa from 'koa'; 3 | 4 | // koa has built-in IP, but maybe not as reliable... see https://github.com/koajs/koa/issues/599 5 | // will check with some real data 6 | export async function detectClientIp(ctx: Koa.Context, next: Koa.Next) { 7 | ctx.state.clientIp = requestIp.getClientIp(ctx.request); 8 | return next(); 9 | } 10 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/lib/defer-promise.ts: -------------------------------------------------------------------------------- 1 | // useful when you need to export a promise before ready to start whatever will initialize it 2 | // should be used sparingly 3 | export function createDeferredPromise() { 4 | // set to noop, but they will be replaced immediately 5 | let resolve: (value?: T) => void = () => {}; 6 | let reject: (reason?: unknown) => void = () => {}; 7 | const promise = new Promise((_resolve, _reject) => { 8 | resolve = _resolve; 9 | reject = _reject; 10 | }); 11 | 12 | return { promise, resolve, reject }; 13 | } 14 | 15 | export type DeferredPromise = ReturnType>; 16 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/lib/querystring.ts: -------------------------------------------------------------------------------- 1 | import Url from 'url'; 2 | 3 | export function getQueryString(obj: Record) { 4 | return new Url.URLSearchParams(obj).toString(); 5 | } 6 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/lib/this-file-path.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url'; 2 | import path from 'node:path'; 3 | 4 | // replacement for __filename and __dirname in esm 5 | // see https://humanwhocodes.com/snippets/2023/01/mimicking-dirname-filename-nodejs-esm/ 6 | // these must be called with `import.meta.url` passed into the arg 7 | 8 | // ex: `const __filename = getThisFilename(import.meta.url);` 9 | 10 | export function getThisFilename(importMetaUrl: string) { 11 | return fileURLToPath(importMetaUrl); 12 | } 13 | export function getThisDirname(importMetaUrl: string) { 14 | return path.dirname(getThisFilename(importMetaUrl)); 15 | } 16 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/lib/tracker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * small wrapper for tracking so we can pass in our domain objects 3 | * and get consistently formatted data 4 | */ 5 | import * as _ from 'lodash-es'; 6 | import { User } from '@prisma/client'; 7 | import { posthog } from './posthog'; 8 | 9 | function identifyUser(user: User) { 10 | posthog.identify({ 11 | distinctId: user.id, 12 | properties: { 13 | // TODO: convert to snake_case?? 14 | ..._.pick(user, [ 15 | 'auth0Id', 16 | 'email', 17 | 'firstName', 18 | 'lastName', 19 | 'nickname', 20 | 'githubUsername', 21 | 'discordUsername', 22 | ]), 23 | }, 24 | }); 25 | } 26 | 27 | function trackEvent(user: User, eventName: string, properties?: any) { 28 | posthog.capture({ 29 | distinctId: user.id, 30 | event: `aa-${eventName}`, 31 | properties, 32 | }); 33 | } 34 | 35 | export const tracker = { 36 | identifyUser, 37 | trackEvent, 38 | }; 39 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/lib/try-catch.ts: -------------------------------------------------------------------------------- 1 | import isPromise from 'is-promise'; 2 | 3 | // see https://www.npmjs.com/package/no-try for inspiration 4 | // although their focus was not on the typing... 5 | // this is more about avoiding an explicitly typed `let thing: TypeOfThingFromInsideTry;` above the try/catch scope 6 | 7 | /** try-catch alternative that exposes a _typed response_ rather than having it stuck in the try's scope */ 8 | export async function tryCatch( 9 | tryFn: () => T | Promise, 10 | catchFn: (e: any) => void | Promise, 11 | ): Promise { 12 | try { 13 | return await tryFn(); 14 | } catch (err) { 15 | const catchResult = catchFn(err); 16 | if (isPromise(catchResult)) { 17 | await catchResult; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/lib/validation-helpers.ts: -------------------------------------------------------------------------------- 1 | import Zod from 'zod'; 2 | import { ApiError } from './api-error'; 3 | 4 | export function validate(obj: any, schema: Z) { 5 | try { 6 | return schema.parse(obj) as Zod.infer; 7 | } catch (err) { 8 | if (!(err instanceof Zod.ZodError)) throw err; 9 | 10 | const firstError = err.errors[0]; 11 | const pathStr = firstError.path.join('.'); 12 | 13 | throw new ApiError('BadRequest', 'ValidationError', `Invalid \`${pathStr}\` - ${firstError.message}`); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example-repo/packages/api/src/scripts/check-env.ts: -------------------------------------------------------------------------------- 1 | import 'dmno/auto-inject-globals'; 2 | 3 | console.log('Checking if ENV is loaded...'); 4 | console.log('-- process.env --------------------'); 5 | console.log(process.env.API_ONLY); 6 | console.log('-- DMNO_CONFIG --------------------'); 7 | console.log(DMNO_CONFIG.API_ONLY); 8 | 9 | 10 | -------------------------------------------------------------------------------- /example-repo/packages/api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "ts-node": { 3 | "swc": true, 4 | }, 5 | "compilerOptions": { 6 | "module": "Preserve", 7 | "target": "ESNext", 8 | "lib": [ 9 | "ESNext" 10 | ], 11 | "strict": true, 12 | "moduleResolution": "Bundler", 13 | "allowSyntheticDefaultImports": true, 14 | "outDir": "dist", 15 | "rootDir": "./", 16 | }, 17 | "include": [ 18 | "src/**/*.ts", 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /example-repo/packages/api/tsup.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import { defineConfig } from 'tsup'; 3 | 4 | export default defineConfig({ 5 | entry: [ // Entry point(s) 6 | 'src/main.ts', // main entry point 7 | ], 8 | 9 | dts: true, // Generate .d.ts files 10 | // minify: true, // Minify output 11 | sourcemap: true, // Generate sourcemaps 12 | treeshake: true, // Remove unused code 13 | 14 | clean: true, // Clean output directory before building 15 | outDir: 'dist', // Output directory 16 | 17 | format: ['esm'], // Output format(s) 18 | 19 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 20 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 21 | }); 22 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/.env.sample: -------------------------------------------------------------------------------- 1 | # some info about this in the example file 2 | ENV_VAR_1="example-value" 3 | 4 | ANOTHER_KEY="" # another comment 5 | 6 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.local 19 | .env.production 20 | 21 | # macOS-specific files 22 | .DS_Store 23 | 24 | # jetbrains setting folder 25 | .idea/ 26 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "astro-web", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro check && astro build", 9 | "preview": "astro preview", 10 | "ssr:dev": "TEST_ASTRO_SSR=1 astro dev", 11 | "ssr:build": "astro check && TEST_ASTRO_SSR=1 PUBLIC_STATIC=ps-build PUBLIC_DYNAMIC=pd-build FOO=foo-build astro build", 12 | "ssr:preview": "PUBLIC_STATIC=ps-boot PUBLIC_DYNAMIC=pd-boot FOO=foo-boot pnpm exec dmno run -- node dist/server/entry.mjs", 13 | "astro": "astro" 14 | }, 15 | "dependencies": { 16 | "@astrojs/check": "^0.5.10", 17 | "@astrojs/mdx": "^2.3.1", 18 | "@astrojs/node": "^8.2.5", 19 | "@astrojs/vue": "^4.1.0", 20 | "@dmno/astro-integration": "link:../../../packages/integrations/astro", 21 | "@dmno/eslint-config": "link:../../../packages/eslint-config", 22 | "astro": "^4.9.1", 23 | "dmno": "link:../../../packages/core", 24 | "typescript": "^5.4.5", 25 | "vue": "^3.4.23" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/example-repo/packages/astro-web/public/favicon.ico -------------------------------------------------------------------------------- /example-repo/packages/astro-web/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/components/ServerVueConfigTest.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 32 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/dmno-vue.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Extra file required if you want to use dmno globals within vue templates 3 | also need to inject into `app.config.globalProperties` 4 | */ 5 | import type { DmnoGeneratedPublicConfigSchema, DmnoGeneratedConfigSchema } from "../.dmno/.typegen/schema"; 6 | 7 | declare module 'vue' { 8 | interface ComponentCustomProperties { 9 | DMNO_PUBLIC_CONFIG: DmnoGeneratedPublicConfigSchema; 10 | DMNO_CONFIG: DmnoGeneratedConfigSchema; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/pages/intercept-test.astro: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | 4 | // this request should be intercepted because of the sensitive secret being sent to the wrong domain 5 | const apiResp = await fetch('https://api.my-logging-provider.com/ingest', { 6 | headers: { 7 | 'x-custom-auth': DMNO_CONFIG.STRIPE_SECRET_KEY, 8 | 'x-another': 'bloop', 9 | }, 10 | }); 11 | 12 | const beers = await apiResp.json(); 13 | 14 | // export const prerender = true; 15 | --- 16 |

Testing http interceptor!

17 |

This page should fail - the request should be intercepted because a sensitive config item was sent as a header to a domain not in the allow list

18 |
{ JSON.stringify(beers) }
19 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/pages/intercept-test.json.ts: -------------------------------------------------------------------------------- 1 | // export const prerender = true; 2 | 3 | export async function GET() { 4 | // this request should be intercepted because of the sensitive secret being sent to the wrong domain 5 | const apiResp = await fetch('https://api.sampleapis.com/beers/ale', { 6 | headers: { 7 | 'x-custom-auth': DMNO_CONFIG.SECRET_FOO, 8 | 'x-another': 'bloop', 9 | }, 10 | }); 11 | return new Response(JSON.stringify(await apiResp.json())); 12 | } 13 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/pages/mdx-test.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: DMNO + MDX test 3 | --- 4 | 5 | 6 | Hello this is a test of mdx 7 | 8 | {/* - DMNO_PUBLIC_CONFIG.FOO - { DMNO_PUBLIC_CONFIG.FOO } 9 | - DMNO_PUBLIC_CONFIG.PUBLIC_FOO - { DMNO_PUBLIC_CONFIG.PUBLIC_FOO } 10 | - DMNO_CONFIG.PUBLIC_FOO - { DMNO_CONFIG.PUBLIC_FOO } */} 11 | 12 | {/* throws with LEAK error */} 13 | {/* - DMNO_CONFIG.SECRET_FOO - { DMNO_CONFIG.SECRET_FOO } */} 14 | 15 | {/* throws, but ts not showing error */} 16 | {/* - DMNO_CONFIG.NOEXIST - { DMNO_CONFIG.NOEXIST } */} 17 | 18 | {/* throws, but ts not showing error */} 19 | {/* - DMNO_PUBLIC_CONFIG.SECRET_FOO - { DMNO_PUBLIC_CONFIG.SECRET_FOO } */} 20 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/pages/middleware-test.astro: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | 4 | // this page should be intercepted because a sensitive item is included in the content 5 | const apiResp = await fetch('https://api.sampleapis.com/coffee/hot'); 6 | 7 | const drinks = await apiResp.json(); 8 | 9 | // export const prerender = true; 10 | --- 11 |

Testing leak detection middleware!

12 |

This page should fail - the page content includes a sensitive config item 13 |

{ JSON.stringify(drinks) }
14 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/pages/middleware-test.json.ts: -------------------------------------------------------------------------------- 1 | // export const prerender = true; 2 | 3 | export async function GET() { 4 | 5 | const apiResp = await fetch('https://api.sampleapis.com/coffee/hot'); 6 | 7 | return new Response(JSON.stringify(await apiResp.json())); 8 | } 9 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/src/vue-app-config.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue'; 2 | 3 | export default (app: App) => { 4 | app.config.globalProperties.DMNO_CONFIG = (globalThis as any).DMNO_CONFIG; 5 | app.config.globalProperties.DMNO_PUBLIC_CONFIG = (globalThis as any).DMNO_PUBLIC_CONFIG; 6 | }; 7 | -------------------------------------------------------------------------------- /example-repo/packages/astro-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "customConditions": [ "ts-src" ] 6 | }, 7 | "exclude": [ "dist", "~partytown" ] 8 | } 9 | -------------------------------------------------------------------------------- /example-repo/packages/dmno-ui-demo/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/dmno-ui-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dmno-ui-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "author": "", 7 | "license": "MIT", 8 | "scripts": { 9 | }, 10 | "devDependencies": { 11 | "@dmno/1password-plugin": "link:../../../packages/plugins/1password", 12 | "dmno": "link:../../../packages/core" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /example-repo/packages/express-js/.dmno/config.mts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, defineDmnoService, pick } from 'dmno'; 2 | 3 | export default defineDmnoService({ 4 | name: 'express-js', 5 | icon: 'skill-icons:expressjs-light', 6 | schema: { 7 | NODE_ENV: pick(), 8 | PUBLIC_EXAMPLE: { 9 | value: 'public!', 10 | }, 11 | SECRET_EXAMPLE: { 12 | value: 'private!', 13 | }, 14 | PORT: { 15 | extends: 'number', 16 | value: 3000, 17 | required: true, 18 | description: 'The port the app should listen on' 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /example-repo/packages/express-js/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/express-js/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// -------------------------------------------------------------------------------- /example-repo/packages/express-js/main.js: -------------------------------------------------------------------------------- 1 | import('dmno/auto-inject-globals'); 2 | const express = require('express') 3 | const app = express() 4 | const port = 3000 5 | 6 | app.get('/', (req, res) => { 7 | res.json({ 8 | status: 'ok!', 9 | config: { 10 | public: DMNO_CONFIG.PUBLIC_EXAMPLE, 11 | private: DMNO_CONFIG.SECRET_EXAMPLE, 12 | } 13 | }) 14 | }) 15 | 16 | app.listen(DMNO_CONFIG.PORT, () => { 17 | console.log(`Example app listening on port ${port}`) 18 | }) 19 | -------------------------------------------------------------------------------- /example-repo/packages/express-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-js", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "dmno run -w -- node main.js", 8 | "boot": "dmno run -- node main.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "dmno": "link:../../../packages/core", 16 | "express": "^4.19.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example-repo/packages/fastify/.dmno/config.mts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, defineDmnoService } from 'dmno'; 2 | 3 | export default defineDmnoService({ 4 | settings: { 5 | preventClientLeaks: true 6 | }, 7 | schema: { 8 | PORT: { 9 | extends: DmnoBaseTypes.port, 10 | value: 3001 11 | }, 12 | SOME_SECRET: { 13 | value: 'shhh-dont-leak-me', 14 | sensitive: true, 15 | } 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /example-repo/packages/fastify/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } -------------------------------------------------------------------------------- /example-repo/packages/fastify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fastify", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "dmno run -w -- vite-node --watch src/index.ts" 9 | }, 10 | "keywords": [ ], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "dmno": "link:../../../packages/core", 15 | "@dmno/fastify-integration": "link:../../../packages/integrations/fastify", 16 | "fastify": "^5.1.0" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^20.12.7", 20 | "fastify-tsconfig": "^2.0.0", 21 | "vite": "^5", 22 | "vite-node": "^2.1.8" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example-repo/packages/fastify/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /example-repo/packages/fastify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "fastify-tsconfig", 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "sourceMap": true, 6 | "composite": true, 7 | "types": [ "vite/client" ], 8 | "strict": true 9 | }, 10 | "include": [ 11 | "src/**/*.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /example-repo/packages/group1/.dmno/config.mts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, defineDmnoService, pick } from 'dmno'; 2 | import { OnePasswordDmnoPlugin } from '@dmno/1password-plugin'; 3 | 4 | const OnePassBackend = OnePasswordDmnoPlugin.injectInstance('1pass'); 5 | 6 | export default defineDmnoService({ 7 | name: 'group1', 8 | schema: { 9 | PICK_TEST_G1: { 10 | extends: pick('root', 'PICK_TEST'), 11 | // TODO: reimpliment transforms 12 | // transformValue: (val) => `${val}-group1transform`, 13 | }, 14 | GROUP1_THINGY: { 15 | extends: DmnoBaseTypes.number, 16 | description: 'thing related to only group1', 17 | }, 18 | OP_TEST: { 19 | value: OnePassBackend.item(), 20 | } 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /example-repo/packages/group1/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/group1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@example/group1", 3 | "private": true, 4 | "version": "0.0.0", 5 | "dependencies": { 6 | "dmno": "link:../../../packages/core" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/next.config.mjs: -------------------------------------------------------------------------------- 1 | import { dmnoNextConfigPlugin } from '@dmno/nextjs-integration'; 2 | /** @type {import('next').NextConfig} */ 3 | const nextConfig = { 4 | 5 | // totally static mode - builds to `out` dir 6 | output: process.env.NEXT_OUTPUT_EXPORT ? 'export' : undefined, 7 | 8 | experimental: { 9 | // instrumentationHook: true, 10 | esmExternals: 'loose', 11 | } 12 | // rest of user config... 13 | }; 14 | 15 | export default dmnoNextConfigPlugin()(nextConfig); 16 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/api/fetch-dynamic-public-config/route.ts: -------------------------------------------------------------------------------- 1 | export const dynamic = process.env.NEXT_OUTPUT_EXPORT ? 'auto' : 'force-dynamic'; 2 | 3 | export async function GET() { 4 | return Response.json((globalThis as any)._DMNO_PUBLIC_DYNAMIC_OBJ); 5 | } 6 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/app/api-edge/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from "next/server"; 2 | 3 | export const runtime = 'edge'; 4 | 5 | console.log('secret foo = '+DMNO_CONFIG.SECRET_FOO); 6 | console.log('secret static = '+DMNO_CONFIG.SECRET_STATIC); 7 | 8 | export async function GET(request: Request) { 9 | console.log('secret foo = '+DMNO_CONFIG.SECRET_FOO); 10 | console.log('secret static = '+DMNO_CONFIG.SECRET_STATIC); 11 | 12 | const url = new URL(request.url); 13 | const query = new URLSearchParams(url.searchParams); 14 | 15 | const r = Response.json({ 16 | PUBLIC_STATIC: DMNO_PUBLIC_CONFIG.PUBLIC_STATIC, 17 | PUBLIC_DYNAMIC: DMNO_PUBLIC_CONFIG.PUBLIC_DYNAMIC, 18 | ...query.get('leak') && { 19 | SECRET_FOO: DMNO_CONFIG.STRIPE_SECRET_KEY, 20 | } 21 | }); 22 | 23 | return r; 24 | } 25 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/app/api-node/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from "next/server"; 2 | 3 | export const runtime = 'nodejs'; 4 | 5 | console.log('secret foo = '+DMNO_CONFIG.SECRET_FOO); 6 | console.log('secret static = '+DMNO_CONFIG.SECRET_STATIC); 7 | 8 | export async function GET(request: Request) { 9 | console.log('secret foo = '+DMNO_CONFIG.SECRET_FOO); 10 | console.log('secret static = '+DMNO_CONFIG.SECRET_STATIC); 11 | 12 | const url = new URL(request.url); 13 | const query = new URLSearchParams(url.searchParams); 14 | 15 | const r = Response.json({ 16 | PUBLIC_STATIC: DMNO_PUBLIC_CONFIG.PUBLIC_STATIC, 17 | PUBLIC_DYNAMIC: DMNO_PUBLIC_CONFIG.PUBLIC_DYNAMIC, 18 | ...query.get('leak') && { 19 | SECRET_FOO: DMNO_CONFIG.STRIPE_SECRET_KEY, 20 | } 21 | }); 22 | 23 | // console.log(r.constructor); 24 | // console.log(r.constructor.prototype); 25 | // console.log(r instanceof Response); 26 | // console.log(Response, globalThis.Response, (globalThis as any).DmnoPatchedResponse); 27 | 28 | return r; 29 | } 30 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/app/intercept-allow/page.tsx: -------------------------------------------------------------------------------- 1 | import { headers } from "next/headers"; 2 | 3 | export default async function ServerTestPage() { 4 | 5 | // the response body includes "Cappuccino" which is set as a sensitive config item 6 | // so we want to make sure our `Response` patchign doesn't interfere with incoming response bodies 7 | const apiResp = await fetch('https://api.sampleapis.com/coffee/hot'); 8 | // console.log(apiResp); 9 | const drinks = await apiResp.json(); 10 | 11 | return ( 12 |
13 |

Intercept test

14 |

this page should be allowed to render

15 |

Fetched response length = { drinks.length }

16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/app/intercept/page.tsx: -------------------------------------------------------------------------------- 1 | import { headers } from "next/headers"; 2 | 3 | export default async function ServerTestPage() { 4 | headers(); 5 | 6 | // console.log(DMNO_CONFIG.SECRET_DYNAMIC); 7 | 8 | // console.log('fetch.__nextPatched ?', (fetch as any).__nextPatched); 9 | console.log(Object.getOwnPropertyDescriptors(fetch)); 10 | 11 | // const apiResp = await fetch('https://api.sampleapis.com/beers/ale', { 12 | const apiResp = await fetch('https://api.my-logging-provider.com/ingest', { 13 | headers: { 14 | 'x-custom-auth': DMNO_CONFIG.STRIPE_SECRET_KEY, 15 | 'x-another': 'bloop', 16 | }, 17 | }); 18 | const beers = await apiResp.json(); 19 | 20 | 21 | return ( 22 |
23 |

Intercept test

24 |
{ JSON.stringify(beers) }
25 | 26 |
27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/app/leak-client/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | export default function LeakPage() { 4 | 5 | return ( 6 |
7 |

Testing CLIENT leak detection

8 |

If you uncomment the line below it should fail the build

9 | {/*
{ DMNO_CONFIG.SECRET_DYNAMIC }
*/} 10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/app/server-action/action.ts: -------------------------------------------------------------------------------- 1 | 'use server' 2 | 3 | 4 | 5 | export async function doServerAction(prevState: any, formData: FormData) { 6 | console.log('Server action!', DMNO_CONFIG.SECRET_DYNAMIC); 7 | return { message: DMNO_CONFIG.SECRET_DYNAMIC }; 8 | } -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/app/server-action/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | export const runtime = 'nodejs'; 4 | 5 | import { useFormState } from "react-dom"; 6 | import { doServerAction } from "./action"; 7 | 8 | const initialState = { 9 | message: null as string | null, 10 | } 11 | 12 | export default function ServerActionTestPage(req: any) { 13 | 14 | const [state, formAction] = useFormState(doServerAction, initialState); 15 | 16 | return ( 17 |
18 |

Server action test

19 |
20 | 21 |
22 |

Message = {state.message}

23 | 24 |
25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/example-repo/packages/nextjs-web/src/app/favicon.ico -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | 29 | @layer utilities { 30 | .text-balance { 31 | text-wrap: balance; 32 | } 33 | } 34 | 35 | #main-nav { 36 | display: flex; 37 | gap: 30px; 38 | } -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | console.log('Redaction test', DMNO_CONFIG.SECRET_FOO); 2 | console.log('Redaction test obj', { secret: DMNO_CONFIG.SECRET_FOO }); 3 | console.log('Redaction test array', ['test', DMNO_CONFIG.SECRET_FOO]); 4 | 5 | export default function Home() { 6 | 7 | return ( 8 |
9 |

use the links above

10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/pages/api/api-edge.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Pages router + edge runtime is not recommended 3 | */ 4 | 5 | import { NextResponse } from 'next/server'; 6 | 7 | export const runtime = 'edge'; 8 | 9 | 10 | export default function handler( 11 | request: Request, 12 | ) { 13 | const url = new URL(request.url); 14 | const query = new URLSearchParams(url.searchParams); 15 | 16 | return NextResponse.json({ 17 | PUBLIC_STATIC: DMNO_PUBLIC_CONFIG.PUBLIC_STATIC, 18 | PUBLIC_DYNAMIC: DMNO_PUBLIC_CONFIG.PUBLIC_DYNAMIC, 19 | ...query.get('leak') && { 20 | SECRET_FOO: DMNO_CONFIG.SECRET_DYNAMIC, 21 | } 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/pages/api/api-node.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from 'next' 2 | 3 | export const runtime = 'nodejs'; 4 | 5 | export default function handler( 6 | req: NextApiRequest, 7 | res: NextApiResponse 8 | ) { 9 | // console.log(typeof res); 10 | // console.log(res.constructor); 11 | // console.log(Object.getPrototypeOf(res.constructor.prototype)); 12 | console.log(res.end.toString()); 13 | 14 | const ofn = res.setHeader; 15 | // @ts-ignore 16 | // res.setHeader = function (...args) { 17 | // console.log('patched set header'); 18 | // // @ts-ignore 19 | // ofn.call(this, args); 20 | // } 21 | // console.log(res.setHeader.toString()); 22 | 23 | // res.status(200).end("foo"); 24 | // res.status(200).json({ foo: 2 }); 25 | 26 | // console.log(res.status(200)) 27 | res.status(200).json({ 28 | PUBLIC_STATIC: DMNO_PUBLIC_CONFIG.PUBLIC_STATIC, 29 | PUBLIC_DYNAMIC: DMNO_PUBLIC_CONFIG.PUBLIC_DYNAMIC, 30 | ...req.query.leak && { 31 | SECRET_FOO: DMNO_CONFIG.SECRET_DYNAMIC, 32 | } 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/pages/api/fetch-dynamic-public-config2.ts: -------------------------------------------------------------------------------- 1 | import type { NextApiRequest, NextApiResponse } from 'next' 2 | 3 | export default function handler( 4 | req: NextApiRequest, 5 | res: NextApiResponse 6 | ) { 7 | res.status(200).json((globalThis as any)._DMNO_PUBLIC_DYNAMIC_OBJ) 8 | } -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/pages/pages/amp.tsx: -------------------------------------------------------------------------------- 1 | export const config = { amp: true } 2 | 3 | // This gets called on every request 4 | export async function getServerSideProps(context: any) { 5 | console.log('DMNO_CONFIG.SECRET_DYNAMIC = ', DMNO_CONFIG.SECRET_DYNAMIC); 6 | // Pass data to the page via props 7 | return { 8 | props: { 9 | data: context.query.leak ? DMNO_CONFIG.SECRET_DYNAMIC : DMNO_PUBLIC_CONFIG.PUBLIC_DYNAMIC 10 | } 11 | }; 12 | } 13 | 14 | 15 | function MyAmpPage(req: any) { 16 | const date = new Date() 17 | 18 | return ( 19 |
20 |

AMP page example

21 |

Some time: {date.toJSON()}

22 |
    23 |
  • Server side data: { req.data }
  • 24 |
25 |
26 | ) 27 | } 28 | 29 | export default MyAmpPage -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/pages/pages/page-edge.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | 3 | export const runtime = 'experimental-edge'; 4 | 5 | 6 | 7 | // This gets called on every request 8 | export async function getServerSideProps(context: any) { 9 | console.log('DMNO_CONFIG.SECRET_DYNAMIC = ', DMNO_CONFIG.SECRET_DYNAMIC); 10 | // Pass data to the page via props 11 | return { 12 | props: { 13 | data: context.query.leak ? DMNO_CONFIG.SECRET_DYNAMIC : DMNO_PUBLIC_CONFIG.PUBLIC_DYNAMIC 14 | } 15 | }; 16 | } 17 | 18 | export default function Page(req: any) { 19 | const router = useRouter() 20 | return
21 |
    22 |
  • Runtime: Nodejs
  • 23 |
  • Router: Pages
  • 24 |
  • Server side data: { req.data }
  • 25 |
26 |
; 27 | } -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/src/pages/pages/page-node.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | 3 | export const runtime = 'nodejs'; 4 | 5 | 6 | 7 | // This gets called on every request 8 | export async function getServerSideProps(context: any) { 9 | console.log('DMNO_CONFIG.SECRET_DYNAMIC = ', DMNO_CONFIG.SECRET_DYNAMIC); 10 | // Pass data to the page via props 11 | return { 12 | props: { 13 | data: context.query.leak ? DMNO_CONFIG.SECRET_DYNAMIC : DMNO_PUBLIC_CONFIG.PUBLIC_DYNAMIC 14 | } 15 | }; 16 | } 17 | 18 | export default function Page(req: any) { 19 | const router = useRouter() 20 | return
21 |
    22 |
  • Runtime: Nodejs
  • 23 |
  • Router: Pages
  • 24 |
  • Server side data: { req.data }
  • 25 |
26 |
; 27 | } -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | const config: Config = { 4 | content: [ 5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | extend: { 11 | backgroundImage: { 12 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", 13 | "gradient-conic": 14 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", 15 | }, 16 | }, 17 | }, 18 | plugins: [], 19 | }; 20 | export default config; 21 | -------------------------------------------------------------------------------- /example-repo/packages/nextjs-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ "dom", "dom.iterable", "esnext" ], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": [ "./src/*" ] 22 | }, 23 | }, 24 | "include": [ 25 | "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", 26 | ], 27 | "exclude": [ "node_modules" ] 28 | } 29 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/.dmno/config.mts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, defineDmnoService, pick } from 'dmno'; 2 | 3 | export default defineDmnoService({ 4 | name: 'nuxt', 5 | icon: 'devicon-plain:nuxtjs', 6 | schema: { 7 | NODE_ENV: pick(), 8 | PUBLIC_EXAMPLE: { 9 | value: 'public!', 10 | }, 11 | SECRET_EXAMPLE: { 12 | value: 'private!', 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | devtools: { enabled: true } 4 | }) 5 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-app", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare" 11 | }, 12 | "dependencies": { 13 | "nuxt": "^3.11.2", 14 | "vue": "^3.4.27", 15 | "vue-router": "^4.3.2" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/example-repo/packages/nuxt-web/public/favicon.ico -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/server/test.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/example-repo/packages/nuxt-web/server/test.ts -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /example-repo/packages/nuxt-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/.dmno/config.mts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, defineDmnoService } from 'dmno'; 2 | 3 | export default defineDmnoService({ 4 | name: 'remix-basic', 5 | icon: 'ri:remix-run-fill', 6 | settings: { 7 | dynamicConfig: 'default_static', 8 | redactSensitiveLogs: true, 9 | // preventClientLeaks: false, 10 | }, 11 | schema: { 12 | PUBLIC_STATIC: { 13 | value: 'public-static-build', 14 | }, 15 | PUBLIC_DYNAMIC: { 16 | value: 'public-dynamic-build', 17 | dynamic: true, 18 | }, 19 | 20 | SECRET_STATIC: { 21 | value: 'secret-static-build', 22 | sensitive: true, 23 | }, 24 | SECRET_DYNAMIC: { 25 | value: 'secret-dynamic-build', 26 | sensitive: true, 27 | dynamic: true, 28 | }, 29 | 30 | STRIPE_SECRET_KEY: { 31 | value: 'super-secret-stripe-key', 32 | sensitive: true, 33 | }, 34 | 35 | // INVALID_ITEM: { 36 | // required: true, 37 | // } 38 | }, 39 | }); 40 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /.cache 4 | /build 5 | .env 6 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to Remix! 2 | 3 | - 📖 [Remix docs](https://remix.run/docs) 4 | 5 | ## Development 6 | 7 | Run the dev server: 8 | 9 | ```shellscript 10 | npm run dev 11 | ``` 12 | 13 | ## Deployment 14 | 15 | First, build your app for production: 16 | 17 | ```sh 18 | npm run build 19 | ``` 20 | 21 | Then run the app in production mode: 22 | 23 | ```sh 24 | npm start 25 | ``` 26 | 27 | Now you'll need to pick a host to deploy it to. 28 | 29 | ### DIY 30 | 31 | If you're familiar with deploying Node applications, the built-in Remix app server is production-ready. 32 | 33 | Make sure to deploy the output of `npm run build` 34 | 35 | - `build/server` 36 | - `build/client` 37 | 38 | ## Styling 39 | 40 | This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever css framework you prefer. See the [Vite docs on css](https://vitejs.dev/guide/features.html#css) for more information. 41 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/app/entry.client.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * By default, Remix will handle hydrating your app on the client for you. 3 | * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ 4 | * For more information, see https://remix.run/file-conventions/entry.client 5 | */ 6 | 7 | import { RemixBrowser } from "@remix-run/react"; 8 | import { startTransition, StrictMode } from "react"; 9 | import { hydrateRoot } from "react-dom/client"; 10 | 11 | startTransition(() => { 12 | hydrateRoot( 13 | document, 14 | 15 | 16 | 17 | ); 18 | }); 19 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/app/root.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Links, 3 | Meta, 4 | Outlet, 5 | Scripts, 6 | ScrollRestoration, 7 | } from "@remix-run/react"; 8 | import "./tailwind.css"; 9 | 10 | export function Layout({ children }: { children: React.ReactNode }) { 11 | return ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {children} 21 | 22 | 23 | 24 | 25 | ); 26 | } 27 | 28 | export default function App() { 29 | return ; 30 | } 31 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/app/routes/api.ts: -------------------------------------------------------------------------------- 1 | import { LoaderFunctionArgs } from "@remix-run/node"; 2 | 3 | export async function loader({ request }: LoaderFunctionArgs): Promise { 4 | const url = new URL(request.url); 5 | 6 | return Response.json({ 7 | PUBLIC_STATIC: DMNO_CONFIG.PUBLIC_STATIC, 8 | PUBLIC_DYNAMIC: DMNO_CONFIG.PUBLIC_DYNAMIC, 9 | 10 | // hit with ?leak=1 to trigger leak detection 11 | ...url.searchParams.get('leak') && { 12 | leak: DMNO_CONFIG.SECRET_STATIC, 13 | } 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/app/routes/server.tsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | export const handle = { hydrate: false }; 4 | 5 | 6 | export default function Page() { 7 | return ( 8 |
9 |

Server-only page?

10 |
    11 |
  • DMNO_CONFIG.PUBLIC_STATIC = { DMNO_CONFIG.PUBLIC_STATIC }
  • 12 | 13 | {/* throws because not a valid config item */} 14 | {/*
  • DMNO_CONFIG.SECRET_STATIC = { DMNO_CONFIG.SECRET_STATIC }
  • */} 15 | 16 | 17 | {/* throws because not a valid config item */} 18 | {/*
  • DMNO_PUBLIC_CONFIG.PUBLIC_STATIC = { DMNO_PUBLIC_CONFIG.BAD_KEY }
  • */} 19 |
20 | 21 |
22 | 23 |
24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/app/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/example-repo/packages/remix-basic/public/favicon.ico -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | export default { 4 | content: ["./app/**/*.{js,jsx,ts,tsx}"], 5 | theme: { 6 | extend: {}, 7 | }, 8 | plugins: [], 9 | } satisfies Config; 10 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "**/*.ts", 4 | "**/*.tsx", 5 | "**/.server/**/*.ts", 6 | "**/.server/**/*.tsx", 7 | "**/.client/**/*.ts", 8 | "**/.client/**/*.tsx" 9 | ], 10 | "compilerOptions": { 11 | "lib": ["DOM", "DOM.Iterable", "ES2022"], 12 | "types": ["@remix-run/node", "vite/client"], 13 | "isolatedModules": true, 14 | "esModuleInterop": true, 15 | "jsx": "react-jsx", 16 | "module": "ESNext", 17 | "moduleResolution": "Bundler", 18 | "resolveJsonModule": true, 19 | "target": "ES2022", 20 | "strict": true, 21 | "allowJs": true, 22 | "skipLibCheck": true, 23 | "forceConsistentCasingInFileNames": true, 24 | "baseUrl": ".", 25 | "paths": { 26 | "~/*": ["./app/*"] 27 | }, 28 | 29 | // Vite takes care of building everything, not tsc. 30 | "noEmit": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example-repo/packages/remix-basic/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { dmnoRemixVitePlugin, dmnoRemixPreset } from "@dmno/remix-integration"; 2 | import { vitePlugin as remix } from "@remix-run/dev"; 3 | import { defineConfig } from "vite"; 4 | import tsconfigPaths from "vite-tsconfig-paths"; 5 | 6 | // console.log('> secret value =', DMNO_CONFIG.SECRET_STATIC); 7 | 8 | console.log('loaded vite.config.ts'); 9 | 10 | export default defineConfig({ 11 | plugins: [ 12 | dmnoRemixVitePlugin(), 13 | remix({ 14 | future: { 15 | v3_fetcherPersist: true, 16 | v3_relativeSplatPath: true, 17 | v3_throwAbortReason: true, 18 | }, 19 | presets: [dmnoRemixPreset()], 20 | }), 21 | tsconfigPaths(), 22 | ], 23 | }); 24 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/vue"], 3 | ignorePatterns: ["dmno-env.d.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Example Web App 9 | 10 | 11 | 12 | 13 |
14 |
    15 |
  • DMNO_PUBLIC_CONFIG.SWITCH_EXAMPLE = %DMNO_PUBLIC_CONFIG.SWITCH_EXAMPLE%
  • 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@example/webapp", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "dev:run": "dmno run -- vite", 9 | "build": "vue-tsc && vite build", 10 | "preview": "vite preview", 11 | "dmno": "dmno resolve", 12 | "dmno:types": "dmno types", 13 | "lint": "eslint src --ext .ts,.cjs", 14 | "lint:fix": "pnpm run lint --fix" 15 | }, 16 | "dependencies": { 17 | "vue": "^3.4.23" 18 | }, 19 | "devDependencies": { 20 | "dmno": "link:../../../packages/core", 21 | "@dmno/eslint-config": "link:../../../packages/eslint-config", 22 | "@dmno/vite-integration": "link:../../../packages/integrations/vite", 23 | "@vitejs/plugin-vue": "^5.0.4", 24 | "typescript": "^5.4.5", 25 | "vite": "^5.2.9", 26 | "vue-tsc": "^2.0.13" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// -------------------------------------------------------------------------------- /example-repo/packages/webapp/src/dmno-vue.d.ts: -------------------------------------------------------------------------------- 1 | import type { DmnoGeneratedPublicConfigSchema, DmnoGeneratedConfigSchema } from '../.dmno/.typegen/schema'; 2 | 3 | declare module 'vue' { 4 | interface ComponentCustomProperties { 5 | DMNO_PUBLIC_CONFIG: DmnoGeneratedPublicConfigSchema; 6 | DMNO_CONFIG: DmnoGeneratedConfigSchema; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import './style.css'; 3 | import App from './App.vue'; 4 | 5 | const app = createApp(App); 6 | 7 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 8 | app.config.globalProperties.DMNO_CONFIG = (globalThis as any).DMNO_CONFIG; 9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 10 | app.config.globalProperties.DMNO_PUBLIC_CONFIG = (globalThis as any).DMNO_PUBLIC_CONFIG; 11 | 12 | app.mount('#app'); 13 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": [ 7 | "ES2020", 8 | "DOM", 9 | "DOM.Iterable" 10 | ], 11 | "skipLibCheck": true, 12 | /* Bundler mode */ 13 | "moduleResolution": "bundler", 14 | "allowImportingTsExtensions": true, 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "noEmit": true, 18 | "jsx": "preserve", 19 | /* Linting */ 20 | "strict": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "noFallthroughCasesInSwitch": true 24 | }, 25 | "include": [ 26 | "src/**/*.ts", 27 | "src/**/*.d.ts", 28 | "src/**/*.tsx", 29 | "src/**/*.vue", 30 | ], 31 | "references": [ 32 | { 33 | "path": "./tsconfig.node.json" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "customConditions": [ "ts-src" ] 9 | }, 10 | "include": [ 11 | "vite.config.ts", 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /example-repo/packages/webapp/vite.config.ts: -------------------------------------------------------------------------------- 1 | 2 | // TODO: need to fix the linting rules so it knows to allow dev deps here 3 | /* eslint-disable import/no-extraneous-dependencies */ 4 | 5 | /// 6 | 7 | import { injectDmnoConfigVitePlugin } from '@dmno/vite-integration'; 8 | import { Plugin, defineConfig } from 'vite'; 9 | import vue from '@vitejs/plugin-vue'; 10 | 11 | // DMNO_CONFIG is avilable here! 12 | // console.log(DMNO_CONFIG.BOOLEAN_EXAMPLE); 13 | 14 | // https://vitejs.dev/config/ 15 | export default defineConfig({ 16 | plugins: [ 17 | // some issues with TS here, I believe it's caused by the local symlink used in our package.json :( 18 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 19 | injectDmnoConfigVitePlugin() as any as Plugin, 20 | vue(), 21 | ], 22 | }); 23 | -------------------------------------------------------------------------------- /example-repo/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | # all packages in direct subdirs of packages/ 3 | - 'packages/*' 4 | -------------------------------------------------------------------------------- /example-repo/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "tasks": { 4 | "build": { 5 | "dependsOn": [ "^build" ], 6 | "inputs": [ "tsconfig.json", "tsconfig.*.json", "tsup.config.ts", "src/**" ], 7 | "outputs": [ "dist/**" ] 8 | }, 9 | "dev": { 10 | "cache": false, 11 | "persistent": true 12 | }, 13 | "env": { } 14 | }, 15 | "globalPassThroughEnv": [ "DMNO_PARENT_SERVER" ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/chat.dmno.dev/README.md: -------------------------------------------------------------------------------- 1 | Just a container for redirecting to the Discord invite 2 | 3 | -------------------------------------------------------------------------------- /packages/chat.dmno.dev/_redirects: -------------------------------------------------------------------------------- 1 | # [YOUR-SUBDOMAIN] [WHERE-YOU-WANT-IT-TO-FORWARD-TO] 2 | https://chat.dmno.dev/* https://discord.gg/sghnJpypf4 301! 3 | -------------------------------------------------------------------------------- /packages/chat.dmno.dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/configraph/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts", "tsup.*.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/configraph/README.md: -------------------------------------------------------------------------------- 1 | # @dmno/configraph [![npm](https://img.shields.io/npm/v/@dmno/configraph)](https://www.npmjs.com/package/@dmno/configraph) 2 | 3 | This library powers the reactive graph at the core of [DMNO](https://dmno.dev). 4 | 5 | It will eventually be released as a standalone library, but we're still actively iterating on it. 6 | 7 | If you're interested in using `configraph` or have any questions, please reach out to us on [Discord](https://chat.dmno.dev). 8 | 9 | For more information on DMNO in general, please see the [DMNO docs](https://dmno.dev/docs). 10 | -------------------------------------------------------------------------------- /packages/configraph/src/common.ts: -------------------------------------------------------------------------------- 1 | export type ExternalDocsEntry = { 2 | description?: string, 3 | url: string, 4 | }; 5 | 6 | // TODO: maybe want to add more restrictions on keys? 7 | // config item keys are all checked against this regex 8 | // currently it must start with a letter (to make it a valid js property) 9 | // and can only contain letters, number, and underscore 10 | // we may want to restrict "__" if we use that as the nesting separator for env var overrides? 11 | export const VALID_NODE_KEY_REGEX = /^[a-z]\w*$/i; 12 | 13 | 14 | // TODO: probably need to allow anything since it can be used in json objects? 15 | export const VALID_NODE_PATH_REGEX = /[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*/i; 16 | 17 | // both of these separators are used within IDs throughout the system 18 | // they should not be valid within npm package names because we default service IDs to the package.json name 19 | // and they should not be the same 20 | 21 | // separates parts of an entity id when it extends a template ex: `someEntity*templateRoot` 22 | export const ENTITY_TEMPLATE_ID_SEP = '*'; 23 | // separates a node full path ex: `entityid!nodepath` 24 | export const NODE_FULL_PATH_SEP = '!'; 25 | -------------------------------------------------------------------------------- /packages/configraph/src/utils/graphlib-utils.ts: -------------------------------------------------------------------------------- 1 | import graphlib from '@dagrejs/graphlib'; 2 | 3 | export function getAllPredecessors(graph: graphlib.Graph, nodeId: string) { 4 | const allPredecessorIds: Record = {}; 5 | const idsToProcess = graph.predecessors(nodeId) || []; 6 | while (idsToProcess.length) { 7 | const nextId = idsToProcess.pop(); 8 | if (!nextId || allPredecessorIds[nextId]) continue; 9 | allPredecessorIds[nextId] = true; 10 | idsToProcess.unshift(...graph.predecessors(nextId) || []); 11 | } 12 | return Object.keys(allPredecessorIds).reverse(); 13 | } 14 | -------------------------------------------------------------------------------- /packages/configraph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // not sure if this should be browser or not? 3 | "extends": "@dmno/tsconfig/tsconfig.node.json", 4 | "compilerOptions": { 5 | "declarationDir": "./dist", 6 | "outDir": "./dist", 7 | // this is needed for vite unfortunately... 8 | // see https://github.com/vitejs/vite/issues/9813 9 | "lib": [ "ES2023", "dom", "dom.iterable" ], 10 | "paths": { 11 | // make self-imports work - helpful for making tests/examples look right 12 | "@dmno/configraph": [ "./src/index.ts" ], 13 | } 14 | }, 15 | "include": [ 16 | "src/**/*.ts", 17 | "src/**/*.d.ts", 18 | "examples/**/*.ts", 19 | "test/**/*.ts", 20 | "*.ts", 21 | "vite.config.mts", 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/configraph/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | ], 7 | 8 | // imported as TS directly, so we have to tell tsup to compile it instead of leaving it external 9 | noExternal: [ 10 | '@dmno/ts-lib', '@dmno/encryption-lib', 11 | ], 12 | external: [ 13 | // '@dmno/configraph' 14 | ], 15 | 16 | dts: true, // Generate .d.ts files 17 | // minify: true, // Minify output 18 | sourcemap: true, // Generate sourcemaps 19 | treeshake: true, // Remove unused code 20 | 21 | // clean: true, // Clean output directory before building 22 | outDir: "dist", // Output directory 23 | 24 | format: ['esm'], // Output format(s) 25 | 26 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 27 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 28 | }); 29 | -------------------------------------------------------------------------------- /packages/configraph/vite.config.mts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | 3 | /// 4 | 5 | import { defineConfig } from 'vitest/config'; 6 | import tsconfigPaths from 'vite-tsconfig-paths'; 7 | 8 | export default defineConfig({ 9 | plugins: [ 10 | tsconfigPaths({ 11 | // extra hint to look in this directory only, otherwise goes all the way up through monorepo 12 | root: __dirname, 13 | }), 14 | ], 15 | test: { 16 | // coverage: { 17 | // exclude: ['src/api'], 18 | // include: ['src'], 19 | // }, 20 | // environment: 'jsdom', 21 | // globals: true, 22 | // setupFiles: './setupTests.ts', 23 | 24 | onConsoleLog(log: string, type: 'stdout' | 'stderr'): false | void { 25 | if (process.env.NO_SWALLOW_LOGS) console.log('log in test: ', log); 26 | if (log === 'message from third party library' && type === 'stdout') { 27 | return false; 28 | } 29 | }, 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /packages/core/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts", "tsup.*.config.ts", "dist", "bin"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/core/README.md: -------------------------------------------------------------------------------- 1 | # DMNO Core [![npm](https://img.shields.io/npm/v/dmno?label=dmno)](https://www.npmjs.com/package/dmno) 2 | 3 | Welcome to `dmno` core which powers `dmno`, and currently includes the config engine, CLI, and associated tools. 4 | 5 | Check out the [docs](https://dmno.dev/docs) for more information on how to use DMNO. 6 | 7 | If you have any questions, please reach out to us on [Discord](https://chat.dmno.dev). 8 | -------------------------------------------------------------------------------- /packages/core/bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import '../dist/cli/cli-executable.js'; 3 | -------------------------------------------------------------------------------- /packages/core/dev-ui-dist: -------------------------------------------------------------------------------- 1 | ../dev-ui/dist -------------------------------------------------------------------------------- /packages/core/src/cli/commands/tapes/base.tape: -------------------------------------------------------------------------------- 1 | # Set up a 1200x600 terminal with 20px font. 2 | Set FontSize 20 3 | Set Width 1200 4 | Set Height 600 5 | 6 | # start in example repo and hide the command 7 | 8 | Hide 9 | Type "cd ../../example-repo/" 10 | Enter 11 | Sleep 500ms 12 | Type "clear" 13 | Enter 14 | Sleep 250ms 15 | Show 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/core/src/cli/commands/tapes/clear-cache.tape: -------------------------------------------------------------------------------- 1 | # relative to /packages/docs-site 2 | # since we will do the docgen from there 3 | Source "../core/src/cli/commands/tapes/base.tape" 4 | 5 | Output "./src/assets/tapes/clear-cache.gif" 6 | 7 | # TODO show a cached value 8 | 9 | Type "pnpm exec dmno resolve -s root" 10 | Enter 11 | Sleep 4000ms 12 | 13 | Type "pnpm exec dmno clear-cache" 14 | Enter 15 | Sleep 5000ms 16 | 17 | # TODO show the cache is cleared and value is new 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/core/src/cli/commands/tapes/dev.tape: -------------------------------------------------------------------------------- 1 | # relative to /packages/docs-site 2 | # since we will do the docgen from there 3 | Source "../core/src/cli/commands/tapes/base.tape" 4 | 5 | Output "./src/assets/tapes/dev.gif" 6 | 7 | Type "pnpm exec dmno dev" 8 | Sleep 500ms 9 | 10 | ## TODO EDIT CONFIG VIA VIM 11 | 12 | Enter 13 | Sleep 1000ms 14 | 15 | Enter 16 | 17 | Sleep 5s 18 | 19 | -------------------------------------------------------------------------------- /packages/core/src/cli/commands/tapes/init.tape: -------------------------------------------------------------------------------- 1 | # relative to /packages/docs-site 2 | # since we will do the docgen from there 3 | Source "../core/src/cli/commands/tapes/base.tape" 4 | 5 | Output "./src/assets/tapes/init.gif" 6 | 7 | Type "pnpm exec dmno init" 8 | Sleep 500ms 9 | 10 | Enter 11 | 12 | Sleep 2000ms 13 | 14 | Down 2 15 | Sleep 1000ms 16 | Up 2 17 | Sleep 1000ms 18 | 19 | Sleep 5s 20 | 21 | -------------------------------------------------------------------------------- /packages/core/src/cli/commands/tapes/plugin.tape: -------------------------------------------------------------------------------- 1 | # relative to /packages/docs-site 2 | # since we will do the docgen from there 3 | Source "../core/src/cli/commands/tapes/base.tape" 4 | 5 | Output "./src/assets/tapes/plugin.gif" 6 | 7 | Type "pnpm exec dmno plugin" 8 | Sleep 500ms 9 | 10 | Enter 11 | 12 | Sleep 3s 13 | 14 | Enter 15 | 16 | Type "pnpm exec dmno plugin -p vault/prod upsert" 17 | 18 | Enter 19 | 20 | Sleep 3s 21 | 22 | Down 2 23 | Sleep 500ms 24 | Up 2 25 | 26 | Sleep 2s 27 | 28 | -------------------------------------------------------------------------------- /packages/core/src/cli/commands/tapes/resolve.tape: -------------------------------------------------------------------------------- 1 | # relative to /packages/docs-site 2 | # since we will do the docgen from there 3 | Source "../core/src/cli/commands/tapes/base.tape" 4 | 5 | Output "./src/assets/tapes/resolve.gif" 6 | 7 | Type "cat .dmno/config.mts" 8 | Enter 9 | Sleep 500ms 10 | 11 | Type "pnpm exec dmno resolve -s root" 12 | Sleep 500ms 13 | 14 | Enter 15 | Sleep 5s 16 | 17 | -------------------------------------------------------------------------------- /packages/core/src/cli/commands/tapes/run.tape: -------------------------------------------------------------------------------- 1 | # relative to /packages/docs-site 2 | # since we will do the docgen from there 3 | Source "../core/src/cli/commands/tapes/base.tape" 4 | 5 | Output "./src/assets/tapes/run.gif" 6 | 7 | Type "pnpm exec dmno run -s root -- printenv SOME_MD5" 8 | Sleep 500ms 9 | 10 | Enter 11 | Sleep 5s 12 | 13 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/cache-helpers.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'commander'; 2 | import { getCliRunCtx } from './cli-ctx'; 3 | import { CliExitError } from './cli-error'; 4 | 5 | export function addCacheFlags(program: Command) { 6 | return program 7 | .option('--skip-cache', 'skips config cache altogether, will not read or write') 8 | .option('--clear-cache', 'clears the cache before continuing, will write new values to cache') 9 | .hook('preAction', async (thisCommand, actionCommand) => { 10 | if (thisCommand.opts().skipCache && thisCommand.opts().clearCache) { 11 | throw new CliExitError('Invalid cli flag combo', { 12 | details: 'Cannot use --skip-cache + --clear-cache at the same time', 13 | forceExit: true, 14 | }); 15 | } 16 | const ctx = getCliRunCtx(); 17 | ctx.dmnoServer.setCacheMode( 18 | (thisCommand.opts().skipCache && 'skip') 19 | || (thisCommand.opts().clearCache && 'clear') 20 | || true, 21 | ); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/cli-error.ts: -------------------------------------------------------------------------------- 1 | import kleur from 'kleur'; 2 | import * as _ from 'lodash-es'; 3 | import { joinAndCompact } from './formatting'; 4 | 5 | export class CliExitError extends Error { 6 | constructor( 7 | message: string, 8 | private more?: { 9 | details?: string | Array, 10 | suggestion?: string | Array, 11 | /** always triggers a full exit, even in watch mode - useful if problem is irrecoverable */ 12 | forceExit?: boolean, 13 | }, 14 | ) { 15 | super(message); 16 | } 17 | 18 | get forceExit() { return !!this.more?.forceExit; } 19 | 20 | getFormattedOutput() { 21 | let msg = `\n💥 ${kleur.red(this.message)} 💥\n`; 22 | 23 | if (this.more?.details) { 24 | msg += joinAndCompact(_.castArray(this.more?.details), '\n'); 25 | } 26 | 27 | if (this.more?.suggestion) { 28 | msg += joinAndCompact(_.castArray(this.more?.suggestion), '\n'); 29 | } 30 | 31 | msg += '\n'; 32 | return msg; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/cli-schema-generation.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash-es'; 2 | import { DmnoCommand } from './dmno-command'; 3 | 4 | // this adds a hidden command which spits out a json schema of the entire cli 5 | export function addDocsCommand(program: DmnoCommand) { 6 | program 7 | .command('get-cli-schema', { hidden: true }) 8 | .action(() => { 9 | const commandsToDocument = program.commands.filter((c) => !(c as any)._hidden); 10 | const commandsSchema = commandsToDocument.map((subCmd) => ({ 11 | command: subCmd.name(), 12 | aliases: subCmd.aliases(), 13 | description: subCmd.description(), 14 | more: _.omit(subCmd, 'parent'), 15 | ...subCmd instanceof DmnoCommand && { 16 | examples: subCmd.examples, 17 | }, 18 | })); 19 | console.log(JSON.stringify(commandsSchema, null, 2)); 20 | process.exit(); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/debug-timer.ts: -------------------------------------------------------------------------------- 1 | import Debug from 'debug'; 2 | 3 | 4 | 5 | 6 | export function createDebugTimer(debugScope = 'debug') { 7 | let lastTimerAt: number | undefined; 8 | const debug = Debug(debugScope); 9 | 10 | return (label: string) => { 11 | if (!lastTimerAt) { 12 | lastTimerAt = +new Date(); 13 | debug(`⏱️ ${label} - start`); 14 | } else { 15 | const now = +new Date(); 16 | const duration = now - lastTimerAt; 17 | debug(`⏱️ ${label} - ${duration}ms`); 18 | lastTimerAt = now; 19 | } 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/diff-utils.ts: -------------------------------------------------------------------------------- 1 | import { diffWords } from 'diff'; 2 | import kleur from 'kleur'; 3 | 4 | export function getDiffColoredText(input: string, output: string): string { 5 | const diffResult = diffWords(input, output); 6 | 7 | if (!diffResult.some((chunk) => chunk.added || chunk.removed)) { 8 | return output; 9 | } 10 | 11 | const diffText = diffResult.map((chunk) => { 12 | if (!chunk.added && !chunk.removed) return chunk.value; 13 | return chunk.value.split('\n') 14 | .map(kleur[chunk.added ? 'green' : 'red']) 15 | .join('\n'); 16 | }).join(''); 17 | 18 | return diffText; 19 | } 20 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/dmno-command.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'commander'; 2 | import * as _ from 'lodash-es'; 3 | 4 | interface CliCommandExample { 5 | command: string; 6 | description: string; 7 | } 8 | 9 | 10 | // extend command class to add an example method which adds examples to the help output 11 | /** 12 | * Extend built in commander.js Command class to add more functionality 13 | * - structured usage examples which can feed into docs and help 14 | * - wrapped action handler, which injects common functionality 15 | */ 16 | export class DmnoCommand extends Command { 17 | /** array of usage examples */ 18 | examples: Array = []; 19 | 20 | /** attach a usage example - feeds into auto-generated docs */ 21 | example(command: string, description: string = '') { 22 | this.examples.push({ command, description }); 23 | return this; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/env-file-helpers.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test, describe } from 'vitest'; 2 | import { stringifyObjectAsEnvFile } from './env-file-helpers'; 3 | 4 | describe('stringifyObjectAsEnvFile', () => { 5 | test('basic', () => { 6 | const result = stringifyObjectAsEnvFile({ foo: 'bar', baz: 'qux' }); 7 | expect(result).toEqual('foo="bar"\nbaz="qux"'); 8 | }); 9 | test('escapes backslashes', () => { 10 | const result = stringifyObjectAsEnvFile({ foo: 'bar\\baz' }); 11 | expect(result).toEqual('foo="bar\\\\baz"'); 12 | }); 13 | test('escapes newlines', () => { 14 | const result = stringifyObjectAsEnvFile({ foo: 'bar\nbaz' }); 15 | expect(result).toEqual('foo="bar\\nbaz"'); 16 | }); 17 | test('escapes double quotes', () => { 18 | const result = stringifyObjectAsEnvFile({ foo: 'bar"baz' }); 19 | expect(result).toEqual('foo="bar\\"baz"'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/env-file-helpers.ts: -------------------------------------------------------------------------------- 1 | export function stringifyObjectAsEnvFile(obj: Record) { 2 | return Object.entries(obj).map(([key, value]) => { 3 | // Handle newlines and quotes by wrapping in double quotes and escaping 4 | const formattedValue = String(value) 5 | .replace(/\\/g, '\\\\') // escape backslashes first 6 | .replace(/\n/g, '\\n') // escape newlines 7 | .replace(/"/g, '\\"'); // escape double quotes 8 | 9 | return `${key}="${formattedValue}"`; 10 | }).join('\n'); 11 | } 12 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/help-customizations.ts: -------------------------------------------------------------------------------- 1 | import { Argument, Command } from 'commander'; 2 | 3 | // override help formatting //////////////////////////////////////////////////////// 4 | function humanReadableArgName(arg: Argument) { 5 | const nameOutput = arg.name() + (arg.variadic === true ? '...' : ''); 6 | return arg.required ? `<${nameOutput}>` : `[${nameOutput}]`; 7 | } 8 | export function customizeHelp(program: Command) { 9 | program.configureHelp({ 10 | // see https://github.com/tj/commander.js/blob/master/lib/help.js#L136 11 | subcommandTerm(cmd) { 12 | const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(' '); 13 | const cmdUsage = (cmd as any)._name 14 | + ((cmd as any)._aliases[0] ? `|${(cmd as any)._aliases[0]}` : '') 15 | + (cmd.options.length ? ' [options]' : '') // simplistic check for non-help option 16 | + (args ? ` ${args}` : ''); 17 | return cmdUsage.replace('', '-- ...'); 18 | }, 19 | }); 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/init-process.ts: -------------------------------------------------------------------------------- 1 | import kleur from 'kleur'; 2 | 3 | process.on('uncaughtException', (err) => { 4 | console.log(kleur.red(`UNCAUGHT EXCEPTION: ${err.message}`)); 5 | console.log(kleur.red(`UNCAUGHT EXCEPTION: ${err.stack}`)); 6 | // eslint-disable-next-line no-restricted-syntax 7 | process.exit(1); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/resolution-context-helpers.ts: -------------------------------------------------------------------------------- 1 | import { Command, Option } from 'commander'; 2 | import { getCliRunCtx } from './cli-ctx'; 3 | import { CliExitError } from './cli-error'; 4 | 5 | const VALID_PHASES = ['build', 'boot']; 6 | 7 | export function addResolutionPhaseFlags(program: Command) { 8 | return program 9 | .addOption(new Option('-p,--phase ', 'resolve in specific phase').choices(VALID_PHASES)) 10 | .hook('preAction', async (thisCommand, actionCommand) => { 11 | const ctx = getCliRunCtx(); 12 | if (thisCommand.opts().phase) { 13 | ctx.dmnoServer.setResolutionPhase(thisCommand.opts().phase); 14 | } 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/shell-helpers.test.ts: -------------------------------------------------------------------------------- 1 | import { execSync, spawn } from 'child_process'; 2 | import { expect, test, describe } from 'vitest'; 3 | import { isSubshell } from './shell-helpers'; 4 | 5 | describe('isSubshell', () => { 6 | test('basic', () => { 7 | expect(isSubshell()).toBe(false); 8 | }); 9 | test('subshell', () => { 10 | const child = spawn('bash', ['-c', 'echo $PPID $(echo $PPID)']); 11 | child.stdout.on('data', () => { 12 | expect(isSubshell()).toBe(true); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/shell-helpers.ts: -------------------------------------------------------------------------------- 1 | export const isSubshell = () => !process.stdin.isTTY; 2 | -------------------------------------------------------------------------------- /packages/core/src/cli/lib/string-utils.ts: -------------------------------------------------------------------------------- 1 | export function stringInsert(index: number, str: string, insertStr: string) { 2 | if (index > 0) return str.substring(0, index) + insertStr + str.substring(index, str.length); 3 | else return insertStr + str; 4 | } 5 | 6 | 7 | 8 | export function getMaxLength(strings: Array, extraBuffer = 4) { 9 | let max = 0; 10 | for (let i = 0; i < strings.length; i++) { 11 | if (strings[i].length > max) max = strings[i].length; 12 | } 13 | if (max) max += extraBuffer; 14 | return max; 15 | } 16 | -------------------------------------------------------------------------------- /packages/core/src/config-engine/data-types.ts: -------------------------------------------------------------------------------- 1 | import { createDmnoDataType, DmnoBaseTypes } from './configraph-adapter'; 2 | 3 | //! IMPORTANT - without this import, TS gets confused about these being the same thing 4 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 5 | import type { ConfigraphDataTypeFactoryFn } from '@dmno/configraph'; 6 | 7 | // example of defining common type using our base types 8 | export const NodeEnvType = createDmnoDataType({ 9 | // TODO: might want to split the base types from these? (both in "dmno/" for now) 10 | typeLabel: 'dmno/nodeEnv', 11 | ui: { icon: 'solar:flag-bold' }, 12 | 13 | typeDescription: 'standard environment flag for Node.js', 14 | extends: DmnoBaseTypes.enum({ 15 | development: { description: 'true during local development' }, 16 | test: { description: 'true while running tests' }, 17 | production: { description: 'true for production' }, 18 | }), 19 | // we'll set the default value, and assume it will be passed in via the environment to override 20 | value: 'development', 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /packages/core/src/external-types/esm-resolve.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'esm-resolve'; 2 | -------------------------------------------------------------------------------- /packages/core/src/external-types/launch-editor.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'launch-editor'; 2 | -------------------------------------------------------------------------------- /packages/core/src/globals-injector/auto-inject.ts: -------------------------------------------------------------------------------- 1 | // this is an entry-point compiled by tsup 2 | // it is meant to be imported directly by node apps as the first line to load config into DMNO_CONFIG global 3 | 4 | import { injectDmnoGlobals as _injectDmnoGlobals } from './injector'; 5 | 6 | let defineInjectedConfig; 7 | try { 8 | // we'll attempt to inject data from a global/replaced var of __DMNO_INJECTED_CONFIG__ 9 | // this is used in something like the cloudflare dwrangler integration, where we use an esbuild replacement 10 | // otherwise we call injectDmnoGlobals() with nothing, and it will look for an env var `DMNO_INJECTED_ENV` 11 | // which would come come something like `dmno run` 12 | 13 | // @ts-ignore 14 | defineInjectedConfig = __DMNO_INJECTED_CONFIG__; 15 | } catch (err) {} 16 | if (defineInjectedConfig) _injectDmnoGlobals({ injectedConfig: defineInjectedConfig }); 17 | else _injectDmnoGlobals(); 18 | 19 | export const injectDmnoGlobals = _injectDmnoGlobals; 20 | 21 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './config-engine/config-engine'; 2 | export * from './config-engine/authoring-utils'; 3 | 4 | export * from './config-engine/configraph-adapter'; 5 | export * from './config-engine/dmno-plugin'; 6 | export * from './config-engine/data-types'; 7 | export * from './config-engine/check-errors-helpers'; 8 | export * from './config-loader/dmno-server'; 9 | export * from './globals-injector/injector'; 10 | 11 | 12 | 13 | export * from './config-loader/serialization-types'; 14 | 15 | export { 16 | DmnoOverrideLoader, OverrideSource, 17 | processEnvOverrideLoader, dotEnvFileOverrideLoader, 18 | } from './config-engine/overrides'; 19 | 20 | // used by 1pass plugin - will likely extract eventually 21 | export * from './lib/dotenv-utils'; 22 | -------------------------------------------------------------------------------- /packages/core/src/lib/constants.ts: -------------------------------------------------------------------------------- 1 | export const GITHUB_REPO_URL = 'https://github.com/dmno-dev/dmno'; 2 | export const DISCORD_INVITE_URL = 'https://chat.dmno.dev'; 3 | -------------------------------------------------------------------------------- /packages/core/src/lib/delay.ts: -------------------------------------------------------------------------------- 1 | export async function promiseDelay(delayInMs: number) { 2 | return new Promise((resolve) => { 3 | setTimeout(resolve, delayInMs); 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /packages/core/src/lib/env-vars.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash-es'; 2 | 3 | let _originalProcessEnv: NodeJS.ProcessEnv; 4 | 5 | /** 6 | * parse env vars into an object, using a special separator to denote nesting. 7 | * This idea comes from https://www.npmjs.com/package/nconf 8 | * 9 | * for example PARENT_ITEM__CHILD_ITEM=foo would result in 10 | * { PARENT_ITEM: { CHILD_ITEM: "foo" } } 11 | */ 12 | export function getConfigFromEnvVars( 13 | /** separator to interpret as nesting, defaults to "__" */ 14 | separator = '__', 15 | ) { 16 | // when we are reloading within the same process 17 | // we must ignore any _new_ process.env vars that dmno injected 18 | if (_originalProcessEnv) { 19 | return _originalProcessEnv; 20 | } 21 | 22 | const configFromProcessEnv = {} as Record; 23 | _.each(process.env, (val, key) => { 24 | const path = key.replaceAll(separator, '.'); 25 | // _.set deals with initializing objects when necessary 26 | _.set(configFromProcessEnv, path, val); 27 | }); 28 | _originalProcessEnv = configFromProcessEnv; 29 | return configFromProcessEnv; 30 | } 31 | -------------------------------------------------------------------------------- /packages/core/src/lib/fs-utils.ts: -------------------------------------------------------------------------------- 1 | import { accessSync } from 'fs'; 2 | import { access } from 'fs/promises'; 3 | 4 | export async function pathExists(p: string) { 5 | try { 6 | await access(p); 7 | return true; 8 | } catch { 9 | return false; 10 | } 11 | } 12 | 13 | export function pathExistsSync(p:string) { 14 | try { 15 | accessSync(p); 16 | return true; 17 | } catch { 18 | return false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/core/src/lib/git-utils.ts: -------------------------------------------------------------------------------- 1 | import { asyncExec } from './exec-helpers'; 2 | 3 | export async function checkIsFileGitIgnored(path: string, warnIfNotGitRepo = false) { 4 | try { 5 | await asyncExec(`git check-ignore ${path} -q`); 6 | return true; 7 | } catch (err) { 8 | // `git check-ignore -q` exits with code 1 but no other error if is not ignored 9 | if ((err as any).stderr === '') return false; 10 | if ((err as any).stderr.includes('not a git repository')) { 11 | if (warnIfNotGitRepo) { 12 | // eslint-disable-next-line no-console 13 | console.log('🔶 Your code is not currently in a git repository - run `git init` to initialize a new repo.'); 14 | } 15 | return false; 16 | } 17 | // otherwise we'll let it throw since something else is happening 18 | throw err; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/core/src/lib/json-utils.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | export function stringifyJsonWithCommentBanner(obj: Record, banner?: string) { 5 | const jsonStringWithoutBanner = JSON.stringify(obj, null, 2); 6 | 7 | const jsonStringWithBanner = [ 8 | '// 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑', 9 | '// 🛑 DO NOT COMMIT THIS FILE TO SOURCE CONTROL', 10 | '// 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑 🛑', 11 | '', 12 | jsonStringWithoutBanner, 13 | ].join('\n'); 14 | 15 | return jsonStringWithBanner; 16 | } 17 | -------------------------------------------------------------------------------- /packages/core/src/lib/patch-response.ts: -------------------------------------------------------------------------------- 1 | /* 2 | This patches the global Response class to scan for secret leaks - currently used for next.js on Vercel in edge runtime only 3 | */ 4 | 5 | export function patchResponseToPreventClientLeaks() { 6 | if ((globalThis.Response as any)._patchedByDmno) { 7 | // console.log('\\n>>>> global Response already patched <<<<< \\n'); 8 | return; 9 | } 10 | 11 | const _UnpatchedResponse = globalThis.Response; 12 | globalThis.Response = class DmnoPatchedResponse extends _UnpatchedResponse { 13 | static _patchedByDmno = true; 14 | constructor(body: any, init: any) { 15 | // console.log('patched Response constructor'); 16 | super((globalThis as any)._dmnoLeakScan(body, { method: 'patched Response constructor' }), init); 17 | } 18 | static json(data: any, init: any) { 19 | // console.log('patched Response.json'); 20 | (globalThis as any)._dmnoLeakScan(JSON.stringify(data), { method: 'patched Response.json' }); 21 | const r = _UnpatchedResponse.json(data, init); 22 | Object.setPrototypeOf(r, Response.prototype); 23 | return r; 24 | } 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /packages/core/src/lib/this-file-path.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url'; 2 | import path from 'node:path'; 3 | 4 | // replacement for __filename and __dirname in esm 5 | // see https://humanwhocodes.com/snippets/2023/01/mimicking-dirname-filename-nodejs-esm/ 6 | // these must be called with `import.meta.url` passed into the arg 7 | 8 | // ex: `const __filename = getThisFilename(import.meta.url);` 9 | 10 | export function getThisFilename(importMetaUrl: string) { 11 | return fileURLToPath(importMetaUrl); 12 | } 13 | export function getThisDirname(importMetaUrl: string) { 14 | return path.dirname(getThisFilename(importMetaUrl)); 15 | } 16 | -------------------------------------------------------------------------------- /packages/core/src/utils.ts: -------------------------------------------------------------------------------- 1 | export { createDeferredPromise, DeferredPromise } from '@dmno/ts-lib'; 2 | export { parseDotEnvContents, parsedDotEnvToObj } from './lib/dotenv-utils'; 3 | export * from './lib/exec-helpers'; 4 | -------------------------------------------------------------------------------- /packages/core/src/vendor-types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './git.vendor-types'; 2 | export * from './postgres.vendor-types'; 3 | 4 | -------------------------------------------------------------------------------- /packages/core/src/vendor-types/postgres.vendor-types.ts: -------------------------------------------------------------------------------- 1 | import { createDmnoDataType, ValidationError } from 'dmno'; 2 | 3 | const PG_REGEX = /(postgres(?:ql)?):\/\/(?:([^@\s]+)@)?([^/\s]+)(?:\/(\w+))?(?:\?(.+))?/; 4 | const ConnectionString = createDmnoDataType({ 5 | typeLabel: 'postgres/connectionString', 6 | extends: 'string', 7 | sensitive: true, 8 | typeDescription: 'Postgres connection url', 9 | externalDocs: { 10 | description: 'explanation from prisma docs', 11 | url: 'https://www.prisma.io/dataguide/postgresql/short-guides/connection-uris#a-quick-overview', 12 | }, 13 | ui: { 14 | icon: 'akar-icons:postgresql-fill', 15 | color: '336791', // postgres brand color :) 16 | }, 17 | 18 | validate(val) { 19 | if (!PG_REGEX.test(val)) return new ValidationError('Invalid postgres connection url'); 20 | }, 21 | }); 22 | 23 | /** 24 | * Placeholder for a few vendor specific data types... 25 | * these will be extracted into separate modules! 26 | */ 27 | export const PostgresDataTypes = { 28 | ConnectionString, 29 | }; 30 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // not sure if this should be browser or not? 3 | "extends": "@dmno/tsconfig/tsconfig.node.json", 4 | "compilerOptions": { 5 | "rootDir": ".", 6 | "declarationDir": "./dist", 7 | "outDir": "./dist", 8 | // this is needed for vite unfortunately... 9 | // see https://github.com/vitejs/vite/issues/9813 10 | "lib": [ "ES2023", "dom", "dom.iterable" ], 11 | "paths": { 12 | // make our self-imports work in our separate exports / entry points 13 | "dmno": [ "./src/index.ts" ], 14 | }, 15 | }, 16 | "include": [ 17 | "src/**/*.ts", "src/**/*.d.ts", 18 | "*.ts", "vite.config.mts", 19 | ], 20 | } 21 | -------------------------------------------------------------------------------- /packages/core/tsconfigs/dmno-folder.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "composite": true, 5 | "strict": true, 6 | "moduleResolution": "Bundler", 7 | "module": "ESNext", 8 | "lib": [ "ESNext" ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/core/vite.config.mts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | 3 | /// 4 | 5 | import { defineConfig } from 'vitest/config'; 6 | 7 | export default defineConfig({ 8 | test: { 9 | // coverage: { 10 | // exclude: ['src/api'], 11 | // include: ['src'], 12 | // }, 13 | // environment: 'jsdom', 14 | // globals: true, 15 | // setupFiles: './setupTests.ts', 16 | onConsoleLog(log: string, type: 'stdout' | 'stderr'): false | void { 17 | if (process.env.NO_SWALLOW_LOGS) console.log('log in test: ', log); 18 | if (log === 'message from third party library' && type === 'stdout') { 19 | return false; 20 | } 21 | }, 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /packages/dev-ui/.dmno/config.mts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, defineDmnoService } from 'dmno'; 2 | 3 | export default defineDmnoService({ 4 | name: 'dev-ui', 5 | schema: { 6 | DEV: {}, 7 | NODE_ENV: {}, 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /packages/dev-ui/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } -------------------------------------------------------------------------------- /packages/dev-ui/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/vue"], 3 | ignorePatterns: [ 4 | "tsup.config.ts", "tsup.*.config.ts", "vite.config.ts" 5 | ], 6 | rules: { 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/dev-ui/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/dev-ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Vite App 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /packages/dev-ui/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/dev-ui/public/favicon.ico -------------------------------------------------------------------------------- /packages/dev-ui/src/assets/base.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | margin: 0; 6 | /* font-weight: normal; */ 7 | } 8 | 9 | body { 10 | min-height: 100vh; 11 | line-height: 1.6; 12 | font-family: 13 | Inter, 14 | -apple-system, 15 | BlinkMacSystemFont, 16 | 'Segoe UI', 17 | Roboto, 18 | Oxygen, 19 | Ubuntu, 20 | Cantarell, 21 | 'Fira Sans', 22 | 'Droid Sans', 23 | 'Helvetica Neue', 24 | sans-serif; 25 | font-size: 14px; 26 | text-rendering: optimizeLegibility; 27 | -webkit-font-smoothing: antialiased; 28 | -moz-osx-font-smoothing: grayscale; 29 | } 30 | 31 | a { 32 | text-decoration: none; 33 | } 34 | -------------------------------------------------------------------------------- /packages/dev-ui/src/assets/main.css: -------------------------------------------------------------------------------- 1 | @import './base.css'; 2 | -------------------------------------------------------------------------------- /packages/dev-ui/src/components/_template.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | 15 | 20 | -------------------------------------------------------------------------------- /packages/dev-ui/src/components/general/DetailsTable/DetailsTable.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 18 | 19 | 26 | -------------------------------------------------------------------------------- /packages/dev-ui/src/components/general/DetailsTable/DetailsTableRow.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 21 | 22 | 39 | -------------------------------------------------------------------------------- /packages/dev-ui/src/components/general/ScrollArea.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 13 | 14 | 29 | -------------------------------------------------------------------------------- /packages/dev-ui/src/components/general/VButton.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /packages/dev-ui/src/components/sidebar/GraphOutline.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 19 | -------------------------------------------------------------------------------- /packages/dev-ui/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /packages/dev-ui/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia'; 2 | import { piniaHooksPlugin } from './plugins/pinia-hooks-plugin'; 3 | 4 | const pinia = createPinia(); 5 | pinia.use(piniaHooksPlugin); 6 | 7 | export default pinia; 8 | -------------------------------------------------------------------------------- /packages/dev-ui/src/utils/dom-utils.ts: -------------------------------------------------------------------------------- 1 | import { unref } from 'vue'; 2 | 3 | export function unwrapDomRef(domRef: any): HTMLElement | undefined { 4 | const el = unref(domRef); 5 | return el.$el || el; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/dev-ui/src/utils/object-utils.ts: -------------------------------------------------------------------------------- 1 | export function eachEntry( 2 | obj: Record, 3 | iterator: ((key: K, val: V) => void), 4 | ) { 5 | Object.entries(obj).forEach(([key, val]) => iterator(key as K, val as V)); 6 | } 7 | -------------------------------------------------------------------------------- /packages/dev-ui/src/views/ConfigOverview.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 33 | -------------------------------------------------------------------------------- /packages/dev-ui/src/views/NotFoundPage.vue: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | -------------------------------------------------------------------------------- /packages/dev-ui/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": [ "env.d.ts", "src/**/*.ts", "src/**/*.vue" ], 4 | "exclude": [ "src/**/__tests__/*" ], 5 | "compilerOptions": { 6 | "customConditions": [ "ts-src" ], 7 | "composite": true, 8 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 9 | "baseUrl": ".", 10 | "paths": { 11 | "@/*": [ "./src/*" ] 12 | }, 13 | // "verbatimModuleSyntax": false 14 | }, 15 | "vueCompilerOptions": { 16 | "plugins": [ 17 | "@vue/language-plugin-pug" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/dev-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/dev-ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node20/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*" 9 | ], 10 | "compilerOptions": { 11 | "rootDir": ".", 12 | "customConditions": [ "ts-src" ], 13 | "composite": true, 14 | "noEmit": true, 15 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 16 | 17 | "module": "ESNext", 18 | "moduleResolution": "Bundler", 19 | "types": [ "node" ], 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/dev-ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueDevTools from 'vite-plugin-vue-devtools' 6 | import basicSSL from '@vitejs/plugin-basic-ssl' 7 | import svgLoader from 'vite-svg-loader' 8 | 9 | import { injectDmnoConfigVitePlugin } from '@dmno/vite-integration'; 10 | 11 | // https://vitejs.dev/config/ 12 | export default defineConfig({ 13 | server: { 14 | port: 4666, 15 | }, 16 | plugins: [ 17 | injectDmnoConfigVitePlugin() as any, 18 | vue(), 19 | vueDevTools(), 20 | svgLoader(), 21 | // self-signed cert just for local dev 22 | // basicSSL({ name: 'dmno-dev' }), 23 | ], 24 | resolve: { 25 | conditions: ['ts-src'], 26 | alias: { 27 | '@': fileURLToPath(new URL('./src', import.meta.url)) 28 | } 29 | }, 30 | }) 31 | -------------------------------------------------------------------------------- /packages/dmno-api/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /packages/dmno-api/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/dmno-api/.gitignore: -------------------------------------------------------------------------------- 1 | .wrangler 2 | -------------------------------------------------------------------------------- /packages/dmno-api/README.md: -------------------------------------------------------------------------------- 1 | # DMNO cloud api 2 | 3 | A simple Hono + Cloudflare workers api. 4 | 5 | Currently this just handles a single endpoint to subscribe folks to our mailing list, but this will be where we can start to deal with user logins and persisting settings/state. 6 | -------------------------------------------------------------------------------- /packages/dmno-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dmno/api", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "dev": "dwrangler dev", 7 | "deploy:staging": "dwrangler deploy --env staging", 8 | "deploy:production": "dwrangler deploy --env production", 9 | "lint": "eslint src --ext .ts,.cjs,.astro,.md,.mdx", 10 | "lint:fix": "pnpm run lint --fix" 11 | }, 12 | "dependencies": { 13 | "@hono/zod-validator": "^0.4.3", 14 | "emailvalid": "^1.0.4", 15 | "hono": "^4.7.4", 16 | "zod": "^3.24.2" 17 | }, 18 | "devDependencies": { 19 | "@cloudflare/workers-types": "^4.20250317.0", 20 | "@dmno/1password-plugin": "workspace:*", 21 | "@dmno/cloudflare-platform": "workspace:*", 22 | "@dmno/eslint-config": "workspace:*", 23 | "dmno": "workspace:*", 24 | "wrangler": "^4.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/dmno-api/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /packages/dmno-api/src/hono-env.ts: -------------------------------------------------------------------------------- 1 | export type CloudflareEnvBindings = { 2 | // DB: D1Database; 3 | }; 4 | export type HonoEnv = { 5 | Bindings: CloudflareEnvBindings; 6 | Variables: { 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /packages/dmno-api/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'dmno/injector-standalone/edge-auto'; 2 | import { Hono } from 'hono'; 3 | import { cors } from 'hono/cors'; 4 | 5 | import { HTTPException } from 'hono/http-exception'; 6 | import { signupRoutes } from './routes/signup.routes'; 7 | import { HonoEnv } from './hono-env'; 8 | import { initErrorHandler } from './lib/error-utils'; 9 | 10 | const app = new Hono().basePath(''); 11 | initErrorHandler(app); 12 | 13 | app.use(cors()); 14 | 15 | app.get('/', async (c) => { 16 | return c.json({ apiStatus: 'ok' }); 17 | }); 18 | 19 | app.route('/', signupRoutes); 20 | 21 | // catch-all 404 22 | app.use(async (c) => { 23 | throw new HTTPException(404, { message: 'Not found' }); 24 | }); 25 | 26 | export default { 27 | fetch: app.fetch, 28 | }; 29 | -------------------------------------------------------------------------------- /packages/dmno-api/src/types/emailvalid.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'emailvalid' { 2 | interface EmailValidationOptions { 3 | allowFreemail?: boolean; 4 | whitelist?: Array; 5 | blacklist?: Array; 6 | allowDisposable?: boolean; 7 | } 8 | 9 | interface ValidationResult { 10 | email: string; 11 | domain: string; 12 | valid: boolean; 13 | errors: Array; 14 | typo: string; 15 | } 16 | 17 | export default class EmailValidation { 18 | constructor(options?: EmailValidationOptions); 19 | check(email: string): ValidationResult; 20 | blacklist(email: string): void; 21 | whitelist(email: string): void; 22 | setOptions(options: EmailValidationOptions): void; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/dmno-api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "lib": [ "ESNext" ], 9 | "types": [ "@cloudflare/workers-types/2023-07-01" ], 10 | }, 11 | "include": [ "src/**/*.ts" ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/dmno-api/wrangler.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/wrangler/config-schema.json", 3 | "name": "dmno-api", 4 | "main": "src/main.ts", 5 | "compatibility_date": "2025-02-03", 6 | "compatibility_flags": [ "nodejs_compat" ], 7 | "observability": { 8 | "enabled": true, 9 | "head_sampling_rate": 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/docs-site/.dmno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "dmno/tsconfigs/dmno-folder", 3 | "include": [ 4 | "./**/*.mts", 5 | "./.typegen/global.d.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /packages/docs-site/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # docgen files 8 | src/utils/typedoc/typedoc-output.json 9 | src/utils/cli.json 10 | -------------------------------------------------------------------------------- /packages/docs-site/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /packages/docs-site/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/docs-site/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | // require('autoprefixer'), 4 | // require('cssnano'), 5 | require('postcss-nested'), 6 | ], 7 | }; 8 | -------------------------------------------------------------------------------- /packages/docs-site/public/_redirects: -------------------------------------------------------------------------------- 1 | /docs/ /docs/get-started/quickstart/ 2 | -------------------------------------------------------------------------------- /packages/docs-site/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/docs-site/public/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/public/og-image.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/blog/1pass/dmno-1password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/blog/1pass/dmno-1password.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/blog/1pass/enable-cli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/blog/1pass/enable-cli.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/blog/1pass/env-blob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/blog/1pass/env-blob.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/blog/screenshot-with-comments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/blog/screenshot-with-comments.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/1pass-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/1pass-demo.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/astro/leaked-secret-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/astro/leaked-secret-error.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/astro/non-existant-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/astro/non-existant-error.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/astro/non-existant-ts-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/astro/non-existant-ts-error.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/astro/non-public-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/astro/non-public-error.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/astro/non-public-ts-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/astro/non-public-ts-error.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/console-redaction-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/console-redaction-demo.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/dynamic-schema-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/dynamic-schema-example.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/footer/theophil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/footer/theophil.jpg -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/intellisense-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/intellisense-demo.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/interceptor-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/interceptor-demo.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/nextjs/intercept-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/nextjs/intercept-error.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/nextjs/leak-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/nextjs/leak-error.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/pick-schema-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/pick-schema-example.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/platform-intellisense-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/platform-intellisense-example.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/plugins/1password/blob-item-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/plugins/1password/blob-item-example.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/reuse-schema-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/reuse-schema-example.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/security-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/security-demo.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/docs-images/validation-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/docs-images/validation-demo.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/houston.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/houston.webp -------------------------------------------------------------------------------- /packages/docs-site/src/assets/private-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/private-link.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/secret-ref.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/secret-ref.png -------------------------------------------------------------------------------- /packages/docs-site/src/assets/square-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/docs-site/src/assets/tapes/clear-cache.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/tapes/clear-cache.gif -------------------------------------------------------------------------------- /packages/docs-site/src/assets/tapes/dev.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/tapes/dev.gif -------------------------------------------------------------------------------- /packages/docs-site/src/assets/tapes/init.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/tapes/init.gif -------------------------------------------------------------------------------- /packages/docs-site/src/assets/tapes/load.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/tapes/load.gif -------------------------------------------------------------------------------- /packages/docs-site/src/assets/tapes/plugin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/tapes/plugin.gif -------------------------------------------------------------------------------- /packages/docs-site/src/assets/tapes/resolve.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/tapes/resolve.gif -------------------------------------------------------------------------------- /packages/docs-site/src/assets/tapes/run.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/docs-site/src/assets/tapes/run.gif -------------------------------------------------------------------------------- /packages/docs-site/src/components/BugReportLink.astro: -------------------------------------------------------------------------------- 1 | --- 2 | interface Props { 3 | label: 4 | | "core" 5 | | "integrations/astro" 6 | | "integrations/vite" 7 | | "integrations/nextjs" 8 | | "plugins/1password" 9 | | "plugins/encrypted-vault"; 10 | repo?: string; 11 | } 12 | 13 | const { label, repo } = Astro.props; 14 | const labels = encodeURIComponent(`${label},bug,triage`); 15 | const titleDefault = encodeURIComponent("[BUG]:"); 16 | 17 | // https://github.com/dmno-dev/dmno/issues/new?assignees=philmillman&labels=bug%2Ctriage%2Cintegrations%2Fnextjs&projects=&template=bug_report.yml&title= 18 | --- 19 | 20 | 24 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/DmnoExecPathAside.md: -------------------------------------------------------------------------------- 1 | :::note[PATH & node_modules/.bin] 2 | The `dmno` cli is installed as a depedency in your project and is available in your `node_modules/.bin` directory. Generally the best way to run it is via your package manager, for example `pnpm exec dmno`. For simplicity's sake, we will omit the `pnpm exec`/`pnpm dlx` prefix in the examples below. 3 | ::: 4 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/GA.astro: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | --- 4 | 5 | 6 | 12 | 20 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/LandingPageSection.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import CTABlock from "./CTABlock.astro"; 3 | 4 | interface Props { 5 | title?: string; 6 | imgPath?: string; 7 | imgAlt?: string; 8 | imgDescription?: string; 9 | ctaLink?: string; 10 | ctaText?: string; 11 | subheader?: string; 12 | } 13 | const { title, imgPath, imgAlt, imgDescription, ctaLink, subheader } = 14 | Astro.props as Props; 15 | --- 16 | 17 |
18 | {title &&

{title}

} 19 | {subheader &&

{subheader}

} 20 | { 21 | imgPath && ( 22 |
23 | {imgAlt} 24 |
{imgDescription}
25 |
26 | ) 27 | } 28 | 29 | 30 | 31 | {ctaLink && } 32 |
33 | 34 | 46 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/PropTable.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // interface Props { 3 | // properties: { 4 | // name: string; 5 | // type: string; 6 | // required: boolean; 7 | // description: string; 8 | // }[]; 9 | // } 10 | 11 | const { properties } = Astro.props; 12 | 13 | // refactor this to actually do the data fecting and just take a string with property list name 14 | --- 15 | 16 | { 17 | properties?.length > 0 ? ( 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {properties.map((property: any) => { 29 | return ( 30 | 31 | 32 | 33 | 34 | 35 | 36 | ); 37 | })} 38 | 39 |
NameTypeRequiredDescription
{property?.name}{property?.type}{property?.required ? "Yes" : "No"}{property?.description}
40 | ) : ( 41 | // TODO - maybe add a better message or just log it 42 |

No properties

43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/SocialIcons.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import DIcon from "./DIcon.astro"; 3 | --- 4 | 5 | 9 | 10 | 37 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/TabbedTypeSettings.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; 3 | import PropTable from "./PropTable.astro"; 4 | 5 | import { 6 | getSettingsForType, 7 | getSchemaStringFromTypes, 8 | } from "../utils/typedoc/baseTypes"; 9 | 10 | const { typeName } = Astro.props; 11 | const typeSettings = getSettingsForType(typeName); 12 | const schemaString = getSchemaStringFromTypes(typeName); 13 | --- 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/VideoBlock.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { muxId } = Astro.props; 3 | --- 4 | 5 |
6 | 12 |
13 | 14 | 15 | 16 | 36 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/homepage/ConfigExample.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Code } from "@astrojs/starlight/components"; 3 | import code2 from "./config-example.ts?raw"; 4 | --- 5 | 6 | 11 | -------------------------------------------------------------------------------- /packages/docs-site/src/components/store.ts: -------------------------------------------------------------------------------- 1 | import { atom } from 'nanostores'; 2 | 3 | export type AvailablePms = 'npm' | 'pnpm' | 'Yarn' | string; 4 | 5 | const storedVal = () => { 6 | if (typeof localStorage !== 'undefined') { 7 | const val = localStorage.getItem('currentPm'); 8 | return val; 9 | } 10 | }; 11 | 12 | const currentPm = atom(storedVal() || 'pnpm'); 13 | 14 | const setCurrentPm = (pm: AvailablePms) => { 15 | currentPm.set(pm); 16 | if (typeof localStorage !== 'undefined') { 17 | localStorage.setItem('currentPm', pm); 18 | } 19 | }; 20 | 21 | const getCurrentPm = () => { 22 | return currentPm.get(); 23 | }; 24 | 25 | export { currentPm, setCurrentPm, getCurrentPm }; 26 | 27 | -------------------------------------------------------------------------------- /packages/docs-site/src/content.config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection, z } from 'astro:content'; 2 | import { docsLoader } from '@astrojs/starlight/loaders'; 3 | import { docsSchema } from '@astrojs/starlight/schema'; 4 | import { blogSchema } from 'starlight-blog/schema'; 5 | 6 | export const collections = { 7 | docs: defineCollection({ 8 | loader: docsLoader(), 9 | schema: docsSchema({ 10 | extend: (context) => ( 11 | blogSchema(context).merge(z.object({ 12 | npmPackage: z.string().optional(), 13 | customHeaderContent: z.string().optional(), 14 | })) 15 | ), 16 | }), 17 | }), 18 | }; 19 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/get-started/sample.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Schema Sample 3 | --- 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/guides/custom-types.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Custom Types 3 | --- 4 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/reference/cli/clear-cache.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: dmno clear-cache 3 | description: Clear the cache using the `dmno clear-cache` command. 4 | --- 5 | 6 | import CliCommand from "@/components/CliCommand.astro"; 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/reference/cli/dev.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: dmno dev 3 | description: Start a development server using the `dmno dev` command. 4 | --- 5 | 6 | import CliCommand from "@/components/CliCommand.astro"; 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/reference/cli/init.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: dmno init 3 | description: Initialize a new DMNO project using the `dmno init` command. 4 | --- 5 | 6 | `dmno init` is the easiest way to get started with DMNO. 7 | 8 | It will automatically detect your project type and install the necessary packages and configuration for you. This includes setting up your `config.mts` file, and creating a `.dmno` directory in the root of your project. It will also import any config items from your `.env` files and add them to the `schema` in your `config.mts` files. Finally, it will install and configure any necessary integrations for your project type. 9 | 10 | import CliCommand from "@/components/CliCommand.astro"; 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/reference/cli/plugin.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: dmno plugin 3 | description: Manage plugins using the `dmno plugin` command. 4 | --- 5 | 6 | import CliCommand from "@/components/CliCommand.astro"; 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/reference/cli/resolve.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: dmno resolve 3 | description: Load the resolved config for a service using the `dmno resolve` command. 4 | --- 5 | 6 | import CliCommand from "@/components/CliCommand.astro"; 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/reference/cli/run.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: dmno run 3 | description: Run a command in the context of a service using the `dmno run` command. 4 | --- 5 | 6 | import CliCommand from "@/components/CliCommand.astro"; 7 | 8 | 9 | 10 | 11 | :::caution 12 | While `dmno run -- echo $SOME_ITEM` seems like it should work, your shell will try to resolve that variable _before_ dmno injects your resolved config as env vars. 13 | 14 | Instead you must use `printenv` - for example `dmno run -- printenv SOME_ITEM`. 15 | ::: 16 | -------------------------------------------------------------------------------- /packages/docs-site/src/content/docs/docs/reference/example.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Example Reference 3 | description: A reference page in my new Starlight docs site. 4 | --- 5 | 6 | Reference pages are ideal for outlining how things work in terse and clear terms. 7 | Less concerned with telling a story or addressing a specific use case, they should give a comprehensive outline of what you're documenting. 8 | 9 | ## Further reading 10 | 11 | - Read [about reference](https://diataxis.fr/reference/) in the Diátaxis framework 12 | -------------------------------------------------------------------------------- /packages/docs-site/src/dmno-env.d.ts: -------------------------------------------------------------------------------- 1 | // inject DMNO_CONFIG global 2 | /// 3 | // inject DMNO_PUBLIC_CONFIG global 4 | /// 5 | -------------------------------------------------------------------------------- /packages/docs-site/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | 5 | declare module 'virtual:starlight/user-config' { 6 | const config: import('@astrojs/starlight/types').StarlightConfig; 7 | 8 | export default config; 9 | } 10 | -------------------------------------------------------------------------------- /packages/docs-site/src/pages/_drafts/integrations.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import LandingPage from '@/components/layouts/LandingPage.astro'; 3 | import VideoBlock from '@/components/VideoBlock.astro'; 4 | import CTABlock from '@/components/CTABlock.astro'; 5 | import Hero from '@/components/Hero.astro'; 6 | 7 | --- 8 | 15 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /packages/docs-site/src/pages/_drafts/platforms.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import LandingPage from '@/components/layouts/LandingPage.astro'; 3 | import VideoBlock from '@/components/VideoBlock.astro'; 4 | import CTABlock from '@/components/CTABlock.astro'; 5 | import Hero from '@/components/Hero.astro'; 6 | 7 | --- 8 | 15 | 19 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /packages/docs-site/src/pages/_drafts/secrets.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import LandingPage from '@/components/layouts/LandingPage.astro'; 3 | import VideoBlock from '@/components/VideoBlock.astro'; 4 | import CTABlock from '@/components/CTABlock.astro'; 5 | import Hero from '@/components/Hero.astro'; 6 | 7 | --- 8 | 15 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /packages/docs-site/src/pages/docs/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | --- 4 | 5 | 6 |

redirecting

7 | 10 | -------------------------------------------------------------------------------- /packages/docs-site/src/style/reset.less: -------------------------------------------------------------------------------- 1 | /* CSS RESET! see https://www.joshwcomeau.com/css/custom-css-reset/ */ 2 | /* 3 | 1. Use a more-intuitive box-sizing model. 4 | */ 5 | *, 6 | *::before, 7 | *::after { 8 | box-sizing: border-box; 9 | } 10 | 11 | /* 12 | 2. Remove default margin 13 | */ 14 | * { 15 | margin: 0; 16 | } 17 | 18 | /* 19 | Typographic tweaks! 20 | 3. Add accessible line-height 21 | 4. Improve text rendering 22 | */ 23 | body { 24 | line-height: 1.5; 25 | -webkit-font-smoothing: antialiased; 26 | } 27 | 28 | /* 29 | 5. Improve media defaults 30 | */ 31 | img, 32 | picture, 33 | video, 34 | canvas, 35 | svg { 36 | display: block; 37 | max-width: 100%; 38 | } 39 | 40 | /* 41 | 6. Remove built-in form typography styles 42 | */ 43 | input, 44 | button, 45 | textarea, 46 | select { 47 | font: inherit; 48 | } 49 | 50 | /* 51 | 7. Avoid text overflows 52 | */ 53 | p, 54 | h1, 55 | h2, 56 | h3, 57 | h4, 58 | h5, 59 | h6 { 60 | overflow-wrap: break-word; 61 | } 62 | 63 | /* 64 | 8. Create a root stacking context 65 | */ 66 | #root, 67 | #__next { 68 | isolation: isolate; 69 | } 70 | 71 | /*****************************/ 72 | -------------------------------------------------------------------------------- /packages/docs-site/src/utils/tapes.js: -------------------------------------------------------------------------------- 1 | import { execSync } from 'child_process'; 2 | 3 | const tape = process.argv[2]; 4 | 5 | // NOTE - you must install vhs locally, which isnt available on npm... 6 | // you can use `brew install vhs` on a mac 7 | const command = `vhs ../core/src/cli/commands/tapes/${tape}.tape`; 8 | 9 | execSync(command, { stdio: 'inherit' }); 10 | -------------------------------------------------------------------------------- /packages/docs-site/src/utils/typedoc/typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "entryPoints": [ 4 | "../../../../core/src/index.ts", 5 | ], 6 | "tsconfig": "../../../../core/tsconfig.json", 7 | "json": "./typedoc-output.json", 8 | "skipErrorChecking": true, 9 | "excludeNotDocumented": true, 10 | "compilerOptions": { 11 | "strictNullChecks": false, 12 | "skipLibCheck": true, 13 | } 14 | } -------------------------------------------------------------------------------- /packages/docs-site/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@/*": [ "src/*" ], 7 | }, 8 | "types": [ 9 | "unplugin-icons/types/raw" 10 | ], 11 | "customConditions": [ "ts-src" ] 12 | }, 13 | "exclude": [ 14 | "dist", "~partytown", 15 | "src/components/homepage/config-example.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/encryption-lib/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | rules: { 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/encryption-lib/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dmno/encryption-lib 2 | 3 | ## 0.0.1 4 | 5 | ### Patch Changes 6 | 7 | - [#65](https://github.com/dmno-dev/dmno/pull/65) [`0a9397b`](https://github.com/dmno-dev/dmno/commit/0a9397b3f65308a899fde1cf4b42c3514ab73fb2) Thanks [@theoephraim](https://github.com/theoephraim)! - installer improvements and fix plugin dmno peerDependency 8 | -------------------------------------------------------------------------------- /packages/encryption-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dmno/encryption-lib", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "main": "src/index.ts", 7 | "types": "src/index.ts", 8 | "scripts": { 9 | "lint": "eslint src --ext .ts,.js,.cjs,.vue", 10 | "lint:fix": "pnpm run lint --fix" 11 | }, 12 | "dependencies": { 13 | "@types/node": "catalog:", 14 | "base64-arraybuffer": "catalog:" 15 | }, 16 | "devDependencies": { 17 | "@dmno/eslint-config": "workspace:*", 18 | "@dmno/tsconfig": "workspace:*" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/encryption-lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // not sure if this should be browser or not? 3 | "extends": "@dmno/tsconfig/tsconfig.node.json", 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": [ 7 | "ESNext", 8 | ], 9 | }, 10 | "include": [ 11 | "src/**/*.ts", 12 | "src/**/*.d.ts", 13 | ] 14 | } -------------------------------------------------------------------------------- /packages/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dmno/eslint-config", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { }, 6 | "exports": { 7 | "./base": "./.eslintrc.base.cjs", 8 | "./vue": "./.eslintrc.vue.cjs" 9 | }, 10 | "devDependencies": { 11 | "@typescript-eslint/eslint-plugin": "^7.1.0", 12 | "@typescript-eslint/parser": "^7.1.0", 13 | "@vue/eslint-config-typescript": "^12.0.0", 14 | "eslint": "^8.57.0", 15 | "eslint-config-airbnb-base": "^15.0.0", 16 | "eslint-config-airbnb-typescript": "^17.1.0", 17 | "eslint-import-resolver-exports": "1.0.0-beta.5", 18 | "eslint-import-resolver-typescript": "^3.6.1", 19 | "eslint-plugin-import": "^2.29.1", 20 | "eslint-plugin-no-autofix": "^1.2.3", 21 | "eslint-plugin-vue": "^9.29.0", 22 | "eslint-plugin-vue-pug": "^0.6.2", 23 | "eslint-import-resolver-custom-alias": "^1.3.2", 24 | "typescript": "catalog:", 25 | "typescript-eslint": "^7.1.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/integrations/astro/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/integrations/astro/dmno.meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrationForPackage": "astro", 3 | "publicPrefix": "PUBLIC_", 4 | "installationCodemods": [ 5 | { 6 | "glob": "astro.config.*", 7 | "imports": [ { 8 | "moduleName": "@dmno/astro-integration", 9 | "importDefaultAs": "dmnoAstroIntegration", 10 | } ], 11 | "updates": [ { 12 | "symbol": "EXPORT", 13 | "path": [ "integrations" ], 14 | "action": { 15 | "arrayContains": "dmnoAstroIntegration()", 16 | }, 17 | } ], 18 | } 19 | ], 20 | } 21 | -------------------------------------------------------------------------------- /packages/integrations/astro/src/astro-middleware.ts: -------------------------------------------------------------------------------- 1 | import { MiddlewareHandler } from 'astro'; 2 | 3 | export const onRequest: MiddlewareHandler = async (context, next) => { 4 | const response = await next(); 5 | 6 | // scan for leaked secrets! 7 | // TODO: binary file types / images / etc dont need to be checked 8 | const bodyText = await response.clone().text(); 9 | (globalThis as any)._dmnoLeakScan(bodyText, { method: 'astro middleware' }); 10 | return response; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/integrations/astro/src/fetch-public-dynamic-config.json.ts: -------------------------------------------------------------------------------- 1 | import type { APIRoute } from 'astro'; 2 | 3 | export const GET: APIRoute = async ({ params, request }) => { 4 | const publicDynamicEnvObj: Record = {}; 5 | for (const itemKey of (globalThis as any)._DMNO_PUBLIC_DYNAMIC_KEYS) { 6 | publicDynamicEnvObj[itemKey] = (globalThis as any).DMNO_PUBLIC_CONFIG[itemKey]; 7 | } 8 | return new Response(JSON.stringify(publicDynamicEnvObj)); 9 | }; 10 | -------------------------------------------------------------------------------- /packages/integrations/astro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/integrations/astro/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | 'src/dev-toolbar-app.ts', // dev toolbar 7 | 'src/astro-middleware.ts', // lead detection middleware 8 | 'src/fetch-public-dynamic-config.json.ts', // injected api route to fetch dynamic public config 9 | ], 10 | 11 | external: [ 12 | "dmno", "astro", 13 | ], 14 | noExternal: ['@dmno/ts-lib', '@dmno/encryption-lib'], 15 | 16 | 17 | dts: true, // Generate .d.ts files 18 | // minify: true, // Minify output 19 | sourcemap: true, // Generate sourcemaps 20 | treeshake: true, // Remove unused code 21 | 22 | clean: true, // Clean output directory before building 23 | outDir: "dist", // Output directory 24 | 25 | format: ['esm'], // Output format(s) 26 | 27 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 28 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 29 | }); 30 | -------------------------------------------------------------------------------- /packages/integrations/fastify/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/integrations/fastify/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dmno/fastify-integration 2 | 3 | ## 0.0.2 4 | 5 | ### Patch Changes 6 | 7 | - [#185](https://github.com/dmno-dev/dmno/pull/185) [`29dcfc2`](https://github.com/dmno-dev/dmno/commit/29dcfc2e6dc9021b30305f694954b4af61dd9d8c) Thanks [@philmillman](https://github.com/philmillman)! - update readmes 8 | 9 | ## 0.0.1 10 | 11 | ### Patch Changes 12 | 13 | - [#174](https://github.com/dmno-dev/dmno/pull/174) [`08f165d`](https://github.com/dmno-dev/dmno/commit/08f165dd6e04a6fe76a904f7501af33ebc201baf) Thanks [@theoephraim](https://github.com/theoephraim)! - initial version of fastify integration 14 | -------------------------------------------------------------------------------- /packages/integrations/fastify/dmno.meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrationForPackage": "fastify" 3 | } 4 | -------------------------------------------------------------------------------- /packages/integrations/fastify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/integrations/fastify/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', 6 | ], 7 | 8 | external: [ 9 | "dmno", 10 | ], 11 | 12 | dts: true, // Generate .d.ts files 13 | // minify: true, // Minify output 14 | sourcemap: true, // Generate sourcemaps 15 | treeshake: true, // Remove unused code 16 | 17 | clean: true, // Clean output directory before building 18 | outDir: "dist", // Output directory 19 | 20 | format: ['esm'], // Output format(s) 21 | 22 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 23 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 24 | }); 25 | -------------------------------------------------------------------------------- /packages/integrations/nextjs/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts", "tsup2.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/integrations/nextjs/dmno.meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrationForPackage": "next", 3 | "publicPrefix": "NEXT_PUBLIC_", 4 | "installationCodemods": [ 5 | { 6 | "glob": "next.config.*", 7 | "imports": [ { 8 | "moduleName": "@dmno/nextjs-integration", 9 | "importVars": [ "dmnoNextConfigPlugin" ], 10 | } ], 11 | "updates": [ { 12 | "symbol": "EXPORT", 13 | "action": { 14 | "wrapWithFn": "dmnoNextConfigPlugin()", 15 | }, 16 | } ] 17 | } 18 | ], 19 | "packageScriptsCodemods": { 20 | "prependDmnoRun": { 21 | "dev": { "command": "next dev", "args": "-w" }, 22 | "build": { "command": "next build" }, 23 | "start": { "command": "next start" }, 24 | "lint": { "command": "next lint" } 25 | } 26 | }, 27 | } 28 | -------------------------------------------------------------------------------- /packages/integrations/nextjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/integrations/nextjs/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | 'src/inject-dmno-client.ts', 7 | ], 8 | 9 | external: [ 10 | "next", 11 | ], 12 | noExternal: [ 13 | 'dmno/inject-globals', 14 | 'dmno/injector-standalone', 15 | 'dmno/injector-standalone-edge', 16 | 'dmno/patch-server-response-standalone' 17 | ], 18 | 19 | dts: true, // Generate .d.ts files 20 | // minify: true, // Minify output 21 | sourcemap: true, // Generate sourcemaps 22 | treeshake: true, // Remove unused code 23 | 24 | clean: false, // Clean output directory before building 25 | outDir: "dist", // Output directory 26 | 27 | format: ['esm', 'cjs'], // Output format(s) 28 | 29 | splitting: false, 30 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 31 | shims: true, 32 | }); 33 | -------------------------------------------------------------------------------- /packages/integrations/remix/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/integrations/remix/dmno.meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrationForPackage": "@remix-run/react", 3 | "publicPrefix": "VITE_", 4 | "installationCodemods": [ 5 | { 6 | "glob": "vite.config.*", 7 | "imports": [ { 8 | "moduleName": "@dmno/remix-integration", 9 | "importVars": [ "dmnoRemixVitePlugin", "dmnoRemixPreset" ], 10 | } ], 11 | "updates": [ 12 | { 13 | "symbol": "EXPORT", 14 | "path": [ "plugins" ], 15 | "action": { 16 | "arrayContains": "dmnoRemixVitePlugin()" 17 | }, 18 | }, 19 | { 20 | "symbol": "remix()", 21 | "path": [ "presets" ], 22 | "action": { 23 | "arrayContains": "dmnoRemixPreset()" 24 | }, 25 | } 26 | ], 27 | } 28 | ], 29 | } 30 | -------------------------------------------------------------------------------- /packages/integrations/remix/src/public-dynamic-config-api-route.ts: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/react'; 2 | 3 | export async function loader(): Promise { 4 | // not sure if we want to wrap this with something, but using `Response.json` didnt work properly 5 | console.log('returning public dynamic config'); 6 | return json((globalThis as any)._DMNO_PUBLIC_DYNAMIC_OBJ); 7 | } 8 | -------------------------------------------------------------------------------- /packages/integrations/remix/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/integrations/remix/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | 'src/public-dynamic-config-api-route.ts', 7 | ], 8 | 9 | external: [ 10 | "dmno", "astro", 11 | ], 12 | noExternal: ['@dmno/ts-lib', '@dmno/encryption-lib'], 13 | 14 | 15 | dts: true, // Generate .d.ts files 16 | // minify: true, // Minify output 17 | sourcemap: true, // Generate sourcemaps 18 | treeshake: true, // Remove unused code 19 | 20 | clean: true, // Clean output directory before building 21 | outDir: "dist", // Output directory 22 | 23 | format: ['esm'], // Output format(s) 24 | 25 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 26 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 27 | }); 28 | -------------------------------------------------------------------------------- /packages/integrations/vite/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/integrations/vite/dmno.meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrationForPackage": "vite", 3 | "publicPrefix": "VITE_", 4 | "installationCodemods": [ 5 | { 6 | "glob": "vite.config.*", 7 | "createFileIfNotFound": { 8 | "fileName": "vite.config.ts", 9 | "contents": "import { defineConfig } from 'vite';\n\nexport default defineConfig({\n plugins: []\n});" 10 | }, 11 | "imports": [ { 12 | "moduleName": "@dmno/vite-integration", 13 | "importVars": [ "injectDmnoConfigVitePlugin" ], 14 | } ], 15 | "updates": [ { 16 | "symbol": "EXPORT", 17 | "path": [ "plugins" ], 18 | "action": { 19 | "arrayContains": "injectDmnoConfigVitePlugin()", 20 | }, 21 | } ], 22 | } 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /packages/integrations/vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/integrations/vite/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | ], 7 | 8 | external: [ 9 | "dmno", "vite", 10 | ], 11 | 12 | dts: true, // Generate .d.ts files 13 | // minify: true, // Minify output 14 | sourcemap: true, // Generate sourcemaps 15 | treeshake: true, // Remove unused code 16 | 17 | clean: true, // Clean output directory before building 18 | outDir: "dist", // Output directory 19 | 20 | format: ['esm'], // Output format(s) 21 | 22 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 23 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 24 | }); 25 | -------------------------------------------------------------------------------- /packages/platforms/cloudflare/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/platforms/cloudflare/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './data-types'; 2 | -------------------------------------------------------------------------------- /packages/platforms/cloudflare/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ], 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts", 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/platforms/cloudflare/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // preset + data types 6 | 'src/dwrangler.ts', 7 | ], 8 | 9 | dts: true, // Generate .d.ts files 10 | // minify: true, // Minify output 11 | sourcemap: true, // Generate sourcemaps 12 | treeshake: true, // Remove unused code 13 | 14 | clean: true, // Clean output directory before building 15 | outDir: "dist", // Output directory 16 | 17 | format: ['esm'], // Output format(s) 18 | 19 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 20 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 21 | }); 22 | -------------------------------------------------------------------------------- /packages/platforms/netlify/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/platforms/netlify/src/build-plugin/manifest.yml: -------------------------------------------------------------------------------- 1 | name: dmno-netlify-build-plugin 2 | -------------------------------------------------------------------------------- /packages/platforms/netlify/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './data-types'; 2 | -------------------------------------------------------------------------------- /packages/platforms/netlify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ], 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts", 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/platforms/netlify/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // preset + data types 6 | 'src/build-plugin/index.ts', 7 | // 'src/build-plugin/injector.ts', 8 | ], 9 | 10 | onSuccess: 'cp src/build-plugin/manifest.yml dist/build-plugin/manifest.yml', 11 | 12 | dts: true, // Generate .d.ts files 13 | // minify: true, // Minify output 14 | sourcemap: true, // Generate sourcemaps 15 | treeshake: true, // Remove unused code 16 | 17 | clean: true, // Clean output directory before building 18 | outDir: "dist", // Output directory 19 | 20 | format: ['esm'], // Output format(s) 21 | 22 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 23 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 24 | }); 25 | -------------------------------------------------------------------------------- /packages/platforms/vercel/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/platforms/vercel/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dmno/vercel-platform 2 | 3 | ## 0.0.3 4 | 5 | ### Patch Changes 6 | 7 | - [#185](https://github.com/dmno-dev/dmno/pull/185) [`29dcfc2`](https://github.com/dmno-dev/dmno/commit/29dcfc2e6dc9021b30305f694954b4af61dd9d8c) Thanks [@philmillman](https://github.com/philmillman)! - update readmes 8 | 9 | ## 0.0.2 10 | 11 | ### Patch Changes 12 | 13 | - [#136](https://github.com/dmno-dev/dmno/pull/136) [`6fffb2e`](https://github.com/dmno-dev/dmno/commit/6fffb2e4bb52be1424c1c8878ad48d6c98c8ae14) Thanks [@theoephraim](https://github.com/theoephraim)! - configraph refactor 14 | 15 | ## 0.0.1 16 | 17 | ### Patch Changes 18 | 19 | - [#106](https://github.com/dmno-dev/dmno/pull/106) [`027d4d6`](https://github.com/dmno-dev/dmno/commit/027d4d699a267b4b29eb3dcc089f15ddf1496c8a) Thanks [@theoephraim](https://github.com/theoephraim)! - add vercel platform, minor adjustments to core and netlify 20 | -------------------------------------------------------------------------------- /packages/platforms/vercel/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './data-types'; 2 | -------------------------------------------------------------------------------- /packages/platforms/vercel/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ], 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts", 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/platforms/vercel/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ 5 | 'src/index.ts', // preset + data types 6 | ], 7 | dts: true, 8 | sourcemap: true, 9 | treeshake: true, 10 | clean: true, 11 | outDir: "dist", 12 | format: ['esm'], 13 | splitting: true, 14 | keepNames: true, 15 | }); 16 | -------------------------------------------------------------------------------- /packages/plugins/1password/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/plugins/1password/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const ONEPASS_ICON = 'simple-icons:1password'; 2 | -------------------------------------------------------------------------------- /packages/plugins/1password/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export * from './data-types'; 4 | export * from './plugin'; 5 | export * from './override-loader'; 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/plugins/1password/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts", 14 | "./.dmno/.typegen/extension-types.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/1password/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | ], 7 | 8 | dts: true, // Generate .d.ts files 9 | // minify: true, // Minify output 10 | sourcemap: true, // Generate sourcemaps 11 | treeshake: true, // Remove unused code 12 | 13 | clean: true, // Clean output directory before building 14 | outDir: "dist", // Output directory 15 | 16 | format: ['esm'], // Output format(s) 17 | 18 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 19 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 20 | }); 21 | -------------------------------------------------------------------------------- /packages/plugins/bitwarden/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/plugins/bitwarden/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dmno/bitwarden-plugin 2 | 3 | ## 0.0.3 4 | 5 | ### Patch Changes 6 | 7 | - [#185](https://github.com/dmno-dev/dmno/pull/185) [`29dcfc2`](https://github.com/dmno-dev/dmno/commit/29dcfc2e6dc9021b30305f694954b4af61dd9d8c) Thanks [@philmillman](https://github.com/philmillman)! - update readmes 8 | 9 | ## 0.0.2 10 | 11 | ### Patch Changes 12 | 13 | - [#182](https://github.com/dmno-dev/dmno/pull/182) [`ada2518`](https://github.com/dmno-dev/dmno/commit/ada25181ea966b3be92b5c8ae061afceb3bc3659) Thanks [@theoephraim](https://github.com/theoephraim)! - add `includeInDmnoConfig` option so items can be exluded from DMNO_CONFIG 14 | 15 | ## 0.0.1 16 | 17 | ### Patch Changes 18 | 19 | - [#148](https://github.com/dmno-dev/dmno/pull/148) [`17191ce`](https://github.com/dmno-dev/dmno/commit/17191ced3d8516b47d6d2657d4c42a077260ca34) Thanks [@theoephraim](https://github.com/theoephraim)! - bitwarden plugin, 1password plugin tweaks, core cleanup 20 | -------------------------------------------------------------------------------- /packages/plugins/bitwarden/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const BITWARDEN_ICON = 'simple-icons:bitwarden'; 2 | -------------------------------------------------------------------------------- /packages/plugins/bitwarden/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export * from './data-types'; 4 | export * from './plugin'; 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/plugins/bitwarden/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts", 14 | "./.dmno/.typegen/extension-types.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/bitwarden/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | ], 7 | 8 | dts: true, // Generate .d.ts files 9 | // minify: true, // Minify output 10 | sourcemap: true, // Generate sourcemaps 11 | treeshake: true, // Remove unused code 12 | 13 | clean: true, // Clean output directory before building 14 | outDir: "dist", // Output directory 15 | 16 | format: ['esm'], // Output format(s) 17 | 18 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 19 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 20 | }); 21 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/src/cli/cli.ts: -------------------------------------------------------------------------------- 1 | import { createDmnoPluginCli } from 'dmno/cli-lib'; 2 | import { SetupCommand } from './setup.command'; 3 | import { AddItemCommand, UpdateItemCommand, UpsertItemCommand } from './upsert.command'; 4 | import { DeleteItemCommand } from './delete.command'; 5 | import { RotateKeyCommand } from './rotate-key.command'; 6 | 7 | const program = createDmnoPluginCli({ 8 | commands: [ 9 | SetupCommand, 10 | UpsertItemCommand, 11 | AddItemCommand, 12 | UpdateItemCommand, 13 | DeleteItemCommand, 14 | RotateKeyCommand, 15 | ], 16 | }); 17 | 18 | // run the cli 19 | await program.parseAsync(); 20 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/src/data-types.ts: -------------------------------------------------------------------------------- 1 | import { DmnoBaseTypes, createDmnoDataType } from 'dmno'; 2 | 3 | const DmnoEncryptionKey = createDmnoDataType({ 4 | typeLabel: 'dmno/encryption-key', 5 | extends: DmnoBaseTypes.string({ 6 | startsWith: 'dmno//', 7 | }), 8 | // TODO: more validation 9 | typeDescription: 'AES-256-GCM encryption key, used for encrypting secrets in dmno', 10 | externalDocs: { 11 | description: 'dmno docs', 12 | url: 'https://dmno.dev/docs/', 13 | }, 14 | ui: { 15 | icon: 'material-symbols:key', 16 | }, 17 | sensitive: true, 18 | includeInDmnoConfig: false, 19 | }); 20 | 21 | export const EncryptedVaultTypes = { 22 | encryptionKey: DmnoEncryptionKey, 23 | }; 24 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export * from './data-types'; 4 | export * from './plugin'; 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/src/lib/helpers.ts: -------------------------------------------------------------------------------- 1 | // TODO: move to core 2 | export function splitFullResolverPath(fullResolverPath: string) { 3 | const [serviceName, itemAndResolverPath] = fullResolverPath.split('!'); 4 | const [itemPath, resolverBranchIdPath] = itemAndResolverPath.split('#'); 5 | return { serviceName, itemPath, resolverBranchIdPath }; 6 | } 7 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/src/lib/vault-file.ts: -------------------------------------------------------------------------------- 1 | export type VaultFile = { 2 | version: string, 3 | keyName: string, 4 | items: Record 8 | }; 9 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts", 14 | "./.dmno/.typegen/extension-types.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/encrypted-vault/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | 'src/cli/cli.ts', // cli entry-point 7 | ], 8 | 9 | // imported as TS directly, so we have to tell tsup to compile it instead of leaving it external 10 | noExternal: ['@dmno/ts-lib', '@dmno/encryption-lib'], 11 | 12 | dts: true, // Generate .d.ts files 13 | // minify: true, // Minify output 14 | sourcemap: true, // Generate sourcemaps 15 | treeshake: true, // Remove unused code 16 | 17 | clean: true, // Clean output directory before building 18 | outDir: "dist", // Output directory 19 | 20 | format: ['esm'], // Output format(s) 21 | 22 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 23 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 24 | }); 25 | -------------------------------------------------------------------------------- /packages/plugins/infisical/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | ignorePatterns: ["tsup.config.ts"], 4 | rules: { 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/plugins/infisical/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @dmno/infisical-plugin 2 | 3 | ## 0.0.3 4 | 5 | ### Patch Changes 6 | 7 | - [#185](https://github.com/dmno-dev/dmno/pull/185) [`29dcfc2`](https://github.com/dmno-dev/dmno/commit/29dcfc2e6dc9021b30305f694954b4af61dd9d8c) Thanks [@philmillman](https://github.com/philmillman)! - update readmes 8 | 9 | ## 0.0.2 10 | 11 | ### Patch Changes 12 | 13 | - [#182](https://github.com/dmno-dev/dmno/pull/182) [`ada2518`](https://github.com/dmno-dev/dmno/commit/ada25181ea966b3be92b5c8ae061afceb3bc3659) Thanks [@theoephraim](https://github.com/theoephraim)! - add `includeInDmnoConfig` option so items can be exluded from DMNO_CONFIG 14 | 15 | ## 0.0.1 16 | 17 | ### Patch Changes 18 | 19 | - [#152](https://github.com/dmno-dev/dmno/pull/152) [`0b25040`](https://github.com/dmno-dev/dmno/commit/0b250403e8f55ae553cab102b3a3b2d9603528d2) Thanks [@philmillman](https://github.com/philmillman)! - New plugin to fetch secrets from Infisical 20 | -------------------------------------------------------------------------------- /packages/plugins/infisical/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const INFISICAL_ICON = 'mdi:infinity'; 2 | -------------------------------------------------------------------------------- /packages/plugins/infisical/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export * from './data-types'; 4 | export * from './plugin'; 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/plugins/infisical/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "module": "ESNext", 6 | "outDir": "dist", 7 | "lib": [ 8 | "ESNext" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.ts", 13 | "src/**/*.d.ts", 14 | "./.dmno/.typegen/extension-types.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/plugins/infisical/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: [ // Entry point(s) 5 | 'src/index.ts', // main lib, users will import from here 6 | ], 7 | 8 | dts: true, // Generate .d.ts files 9 | // minify: true, // Minify output 10 | sourcemap: true, // Generate sourcemaps 11 | treeshake: true, // Remove unused code 12 | 13 | clean: true, // Clean output directory before building 14 | outDir: "dist", // Output directory 15 | 16 | format: ['esm'], // Output format(s) 17 | 18 | splitting: true, // split output into chunks - MUST BE ON! or we get issues with multiple copies of classes and instanceof 19 | keepNames: true, // stops build from prefixing our class names with `_` in some cases 20 | }); 21 | -------------------------------------------------------------------------------- /packages/ts-lib/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/base"], 3 | rules: { 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/ts-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dmno/ts-lib", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "main": "src/index.ts", 7 | "types": "src/index.ts", 8 | "scripts": { 9 | "lint": "eslint src --ext .ts,.js,.cjs,.vue", 10 | "lint:fix": "pnpm run lint --fix" 11 | }, 12 | "dependencies": { 13 | "is-promise": "^4.0.0" 14 | }, 15 | "devDependencies": { 16 | "@dmno/eslint-config": "workspace:*", 17 | "@dmno/tsconfig": "workspace:*" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/ts-lib/src/defer-promise.ts: -------------------------------------------------------------------------------- 1 | // useful when you need to export a promise before ready to start whatever will initialize it 2 | // should be used sparingly 3 | export function createDeferredPromise() { 4 | // set to noop, but they will be replaced immediately 5 | let resolve: (value?: T) => void = (() => {}); 6 | let reject: (reason?: unknown) => void = () => {}; 7 | const promise = new Promise((_resolve, _reject) => { 8 | resolve = _resolve as any; 9 | reject = _reject; 10 | }); 11 | 12 | return { promise, resolve, reject }; 13 | } 14 | 15 | export type DeferredPromise = ReturnType>; 16 | -------------------------------------------------------------------------------- /packages/ts-lib/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './defer-promise'; 2 | export * from './promise-delay'; 3 | export * from './try-catch'; 4 | -------------------------------------------------------------------------------- /packages/ts-lib/src/promise-delay.ts: -------------------------------------------------------------------------------- 1 | export async function promiseDelay(delayInMs: number) { 2 | return new Promise((resolve) => { 3 | setTimeout(resolve, delayInMs); 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /packages/ts-lib/src/try-catch.ts: -------------------------------------------------------------------------------- 1 | import isPromise from 'is-promise'; 2 | 3 | // see https://www.npmjs.com/package/no-try for inspiration 4 | // although their focus was not on the typing... 5 | 6 | /** try-catch alternative that exposes a typed response rather than having it stuck in the try's scope */ 7 | export async function tryCatch( 8 | tryFn: () => T | Promise, 9 | catchFn: (err: Error) => E | Promise, 10 | 11 | // @ts-ignore 12 | ): Promise { 13 | try { 14 | return await tryFn(); 15 | } catch (err) { 16 | let catchResult = catchFn(err as Error); 17 | if (isPromise(catchResult)) { 18 | catchResult = await catchResult; 19 | } 20 | return catchResult; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/ts-lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // not sure if this should be browser or not? 3 | "extends": "@dmno/tsconfig/tsconfig.node.json", 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": [ 7 | // TODO: added this so setTimeout gets resolved properly but this is supposed to be shared utils for browser and node 8 | // so I'm not sure what the right types to include are... 9 | "DOM", 10 | "ESNext", 11 | ], 12 | }, 13 | "include": [ 14 | "src/**/*.ts", 15 | "src/**/*.d.ts", 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dmno/tsconfig", 3 | "private": true, 4 | "version": "0.0.0", 5 | "exports": { 6 | "./tsconfig.browser.json": "./tsconfig.browser.json", 7 | "./tsconfig.node.json": "./tsconfig.node.json" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/tsconfig/tsconfig.browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "declaration": true, 5 | "declarationMap": true, 6 | "useDefineForClassFields": true, 7 | "module": "ES6", 8 | "moduleResolution": "node", 9 | "strict": true, 10 | "jsx": "preserve", 11 | "sourceMap": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "esModuleInterop": true, 15 | "allowSyntheticDefaultImports": true, 16 | "lib": [ 17 | "ES6", 18 | "DOM", 19 | "dom.iterable" 20 | ], 21 | "skipLibCheck": true, 22 | "customConditions": [ "ts-src" ] 23 | }, 24 | "references": [ 25 | { "path": "./tsconfig.node.json" } 26 | ], 27 | "include": [ 28 | "src/**/*.ts", 29 | "src/**/*.d.ts", 30 | "src/**/*.tsx", 31 | "src/**/*.vue" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /packages/tsconfig/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "target": "ES2022", 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | // "moduleResolution": "Node", 8 | "resolveJsonModule": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "declaration": true, 11 | "declarationMap": true, 12 | "lib": [ 13 | "ES2023" 14 | ], 15 | "strict": true, 16 | "allowSyntheticDefaultImports": true, 17 | "esModuleInterop": true, 18 | "customConditions": [ "ts-src" ], 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/ui-lib/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ["@dmno/eslint-config/vue"], 3 | rules: { 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/ui-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dmno/ui-lib", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "exports": { 7 | ".": { 8 | "default": "./src/index.ts" 9 | }, 10 | "./brand-assets/": { 11 | "default": "./src/brand-assets/" 12 | }, 13 | "./style/": { 14 | "default": "./src/style/" 15 | } 16 | }, 17 | "typesVersions": { 18 | "*": { 19 | "index": [ 20 | "./src/index.ts" 21 | ] 22 | } 23 | }, 24 | "scripts": { 25 | "lint": "eslint src --ext .ts,.cjs", 26 | "lint:fix": "pnpm run lint --fix" 27 | }, 28 | "dependencies": { 29 | "vue": "^3.4.21" 30 | }, 31 | "devDependencies": { 32 | "@dmno/eslint-config": "workspace:*", 33 | "@dmno/tsconfig": "workspace:*", 34 | "less": "^4.2.0", 35 | "pug": "^3.0.2", 36 | "typescript": "catalog:" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/ui-lib/src/brand-assets/domino-d-gradient-tile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/ui-lib/src/brand-assets/domino-d-gradient-tile@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/ui-lib/src/brand-assets/domino-d-gradient-tile@2x.png -------------------------------------------------------------------------------- /packages/ui-lib/src/brand-assets/domino-d-gradient.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/ui-lib/src/brand-assets/domino-d-gradient@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/ui-lib/src/brand-assets/domino-d-gradient@2x.png -------------------------------------------------------------------------------- /packages/ui-lib/src/brand-assets/domino-d-plain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/ui-lib/src/brand-assets/domino-d-plain@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmno-dev/dmno/e9c13dad55b3c9cae760e896fa41d2c65103b969/packages/ui-lib/src/brand-assets/domino-d-plain@2x.png -------------------------------------------------------------------------------- /packages/ui-lib/src/brand-assets/domino-logo-only.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/ui-lib/src/components/DmnoD.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 41 | -------------------------------------------------------------------------------- /packages/ui-lib/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DmnoLogo } from './components/DmnoD.vue'; 2 | export { default as DotsLoader } from './components/DotsLoader.vue'; 3 | export { default as DmnoTileLogo } from './components/DmnoTileLogo.vue'; 4 | -------------------------------------------------------------------------------- /packages/ui-lib/src/style/base.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* allows animating unknown height! see https://developer.chrome.com/docs/css-ui/animate-to-height-auto#why_not_allow_animation_to_and_from_sizing_keywords_by_default */ 3 | interpolate-size: allow-keywords; 4 | font-family: var(--body-font); 5 | } 6 | -------------------------------------------------------------------------------- /packages/ui-lib/src/style/utilities.css: -------------------------------------------------------------------------------- 1 | /* 2 | CUSTOM UTILITY CLASSES 3 | 4 | giving them all a prefix of `_` 5 | not quite sure about this yet... we'll see 6 | 7 | */ 8 | 9 | 10 | ._truncate { 11 | line-height: 1cap; 12 | /* extra padding and negative margin helps reveal otherwise cut off ascenders/descenders */ 13 | padding-top: 0.3cap; 14 | padding-bottom: 0.3cap; 15 | margin-top: -0.3cap; 16 | margin-bottom: -0.3cap; 17 | text-overflow: ellipsis; 18 | overflow: hidden; 19 | text-wrap: nowrap; 20 | } 21 | 22 | /* flex/grid parents of truncated text must have min-width: 0 */ 23 | *:has(>._truncate) { 24 | min-width: 0; 25 | } 26 | 27 | 28 | ._cap { 29 | line-height: 1cap; 30 | } 31 | -------------------------------------------------------------------------------- /packages/ui-lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": [ "ES2020", "DOM", "DOM.Iterable" ], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "preserve", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue" ], 24 | "references": [ { "path": "./tsconfig.node.json" } ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/ui-lib/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@dmno/tsconfig/tsconfig.node.json", 3 | "include": [ 4 | ".eslintrc.cjs", 5 | "package.json", 6 | "./*.js", 7 | "./**/*.cjs", 8 | ] 9 | } -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | packages: 3 | - 'packages/*' 4 | - 'packages/plugins/*' 5 | - 'packages/integrations/*' 6 | - 'packages/platforms/*' 7 | 8 | catalog: 9 | "base64-arraybuffer": "^1.0.2" 10 | "debug": "^4.3.4" 11 | "kleur": "^4.1.5" 12 | "lodash-es": "^4.17.21" 13 | "modern-async": "^2.0.4" 14 | "svgo": "^3.2.0" 15 | "tsup": "^8.2.4" 16 | "typescript": "^5.7.2" 17 | "vite": "^5.4.6" 18 | "vite-node": "^2.1.2" 19 | "vitest": "^2.1.5" 20 | "@dagrejs/graphlib": "^2.2.4" 21 | "@scarf/scarf": "^1.4.0" 22 | "@types/debug": "^4.1.12" 23 | "@types/lodash-es": "^4.17.12" 24 | "@types/node": "^20.14.11" 25 | -------------------------------------------------------------------------------- /tea.yaml: -------------------------------------------------------------------------------- 1 | # https://tea.xyz/what-is-this-file 2 | --- 3 | version: 1.0.0 4 | codeOwners: 5 | - '0x590C222616C5c5C359ff64cF1c0f7E532F18F7f7' 6 | - '0xeB88F212459a3a91C88414A57A4e2d62c1cE3E2B' 7 | quorum: 1 8 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "globalPassThroughEnv": [ "CF_PAGES", "CF_PAGES_BRANCH", "CF_PAGES_COMMIT_SHA", "CF_PAGES_URL" ], 4 | "tasks": { 5 | "build": { 6 | "dependsOn": [ "^build" ], 7 | "inputs": [ "tsconfig.json", "tsconfig.*.json", "tsup.config.ts", "src/**" ], 8 | "outputs": [ "dist/**" ] 9 | }, 10 | "build:tarball": { 11 | "dependsOn": [ "^build" ], 12 | "inputs": [ "tsconfig.json", "tsconfig.*.json", "tsup.config.ts", "src/**" ] 13 | }, 14 | "dev": { 15 | "cache": false, 16 | "persistent": true 17 | }, 18 | 19 | "lint": { } 20 | } 21 | } 22 | --------------------------------------------------------------------------------