A package that contains utilities to help you build Astro integrations.
To see how to get started, check out the package README
MIT Licensed. Made with ❤️ by Florian Lefebvre.
A package that contains utilities to help you build Astro integrations.
Home Page: https://astro-integration-kit.netlify.app
License: MIT License
A package that contains utilities to help you build Astro integrations.
To see how to get started, check out the package README
MIT Licensed. Made with ❤️ by Florian Lefebvre.
Don't know what the want for this would be, but is a quick win
https://discord.com/channels/830184174198718474/1207247804058042439
This is more of an RFC I guess, but what do we think about a utility that lets the author create and read files inside a hidden folder just for that integration inside a user's project?
So it'd be something like this:
({ createHiddenFile, readHiddenFile }) => {
createHiddenFile({
name: 'foo.ts',
content: `export default {}`
})
const myHiddenFile = await readHiddenFile('foo.ts')
}
These would then save at ${ root }/.[integration.name]/foo.ts
So right next to the hidden .astro
folder. And it can't read/write outside that folder.
For context, the usecase is:
For my themes, I'm planning on shipping encrypted versions of my component files so that then they can be decrypted on the user's machine if they have the correct permissions with their env variables. So they'll set an env key, it'll check the api for their "level" and then decrypt the components for that level.
But I don't want it to have to make an api call each time they run or build their project. So once it's done one call and gotten the decryption keys I want to store them on the user's machine. Then they can still develop and reinstall and everything without the api.
I realise I could do this relatively easily without a utility. But I'm going to implement this either way, so just wondered if other people thought there'd be any interest in making it an AIK util.
Since they added new support for Astro DB the hooks changed. would be nice to get a patch that
AIK
Extended hooks to use the new Astro v4.5
Hooks@astrojs/db
's new hooksVitePWA
is of type Plugin[]
, but addVitePlugin
takes only Plugin
type.
I know we should probably change the docs example now, but do you plan to receive Plugin[]
in the future?
PS. It's an example, so I'm not sure if it should be changed.
pathe
is already used for createResolver
, but it would be great to update all imports from node:path
to pathe
Thought I might as well add it since I'm happily using it in the Qwik integration.
Feel free to copy paste this to save time haha or whatever you prefer.
[Astro Qwik](https://github.com/QwikDev/astro) - by Jack Shelton
The type for the setup function is declared as receiving TOptions
:
But what it receives is TOptions['options']
:
astro-integration-kit/package/src/core/define-integration.ts
Lines 45 to 48 in b3c3230
TS Doesn't complain about it because since the values are covariant
I just pushed a branch on Astro-Gists I'm getting the following error after upgrading to AIK v0.7
More chat history on AstroLounge Discord / #Integrations
In can be confusing for people to understand what's point of AIK, like you don't technically need it to build an Astro + it's not official. A new page at /getting-started/why/
would help!
that would allow us to do some magic, like for #8
A plugin may define a dependency on another plugin, an idea of API:
import { otherPlugin } from "./other-plugin.js"
export const dependentPlugin = definePlugin({
name: "foo",
hook: "astro:config:setup",
dependsOn: [otherPlugin],
implementation: ({ otherPluginName }) => () => {}
})
It would be great to provide utilities to allow authors easily write their dev toolbar app using their favorite UI framework
If one integration uses all the utilities from the kit show a log " is all-in. Forever remembered!"
Depends on #31
Right now it's not a great contribution experience to require contributors (especially first time ones) to run pnpm lint:fix
. It would be great to have an action that runs on main
and does this. I recommend we use autofix-ci
for this (I think an example can be found on nuxt repo)
It would be great to update the types constraint to allow things .refine
, .transform
on optionsSchema
Would be great to provide a schema to defineOptions
, that would solve a few issues
Just like this kit provides hasIntegration
to check if an integration was already included, it could provide a hasPreviousIntegration
/hasFollowingIntegration
for integrations that interact with others in specific orders (mostly related to markdown and MDX).
This would allow the integration to issue a warning or an error if an integration was added in the incorrect order.
If you do this:
export const somePlugin = definePlugin();
The inferred type of somePlugin
requires importing transitive dependencies to be named (even if it is also your dependency) because it relies on AIK's dependency in Astro.
Because a third-party lib may depend on a different version of Astro, import('astro')
would refer to different types depending on where it is. So TS rejects that just for the possibility, even if it is not really the case.
This problem happens for libs that are transpiled and emit a .d.ts. The two solutions are:
type SomePlugin = Plugin<
'utilityName',
'astro:config:setup',
(p: HookParams) => (params: UtilityParams) => UtilityOutput
>;
export const somePlugin: SomePlugin = definePlugin();
Needs another export (see astro-env)
The barrel export as astro-integration-kit/utilities
causes types for all utilities to be loaded, which requires all optional dependencies to be present, even if unused.
> @inox-tools/[email protected] validate /Users/lotus/IsoWorkspaces/OSS/inox-tools/packages/aik-route-config
> tsc
../../node_modules/.pnpm/[email protected][email protected]/node_modules/astro-integration-kit/src/utilities/add-devtoolbar-framework-app.ts:87:10 - error TS2307: Cannot find module '@vitejs/plugin-react' or its corresponding type declarations.
87 import("@vitejs/plugin-react").then((react) => {
~~~~~~~~~~~~~~~~~~~~~~
Found 1 error in ../../node_modules/.pnpm/[email protected][email protected]/node_modules/astro-integration-kit/src/utilities/add-devtoolbar-framework-app.ts:87
ELIFECYCLE Command failed with exit code 2.
The solution for this is to include a module declaration in the file to prevent the module typing from depending on the presence of the dependency.
Since modules are merged like interfaces, the module declaration can declare a simple export without details.
It's a quite common use-case to need data from a hook into a hook used later on (eg. config
from astro:config:done
inside astro:build:done
). Right now, plugins are bound to a single hook. There may be a way to achieve that, here is an idea of API:
definePlugin({
setup({ name }) {
let config
return {
"astro:config:setup": ({ config: _config }) => {
config = _config
},
"astro:build:done": () => {
// do something with config
}
}
}
})
I'm unsure how the API should look like regarding adding utilities to hooks tho 🤔. Isn't it a better fit for an integration at this point?
Template:
/**
* This is the main important part, describing the thing below.
* Often I **only** use this (at least in TS where typing is in code).
*
* But the following tags come in handy for me too:
*
* @param name Description of a function parameter — even with types provided by TypeScript, sometimes it’s handy to provide extra context/description. I don’t use it all the time though.
*
* @see Handy for linking to another bit of code or docs sometimes (although you can also do that in the main description probably).
*
* @example
* // For more complex functions I might show some example usage
* codeInUse()
*
* @deprecated Handy because editors will give some nice visual feedback with strikethrough and there’s a chance to give users some guidance on what to do instead.
*/
Thanks @delucis 🙏
As requested by Nate, we should prevent users from setting the virtual import name to a string starting with astro:
as it's reserved to core.
At the moment I don't think we'd be able to recreate something like this using the integration kit
https://github.com/lilnasy/gratelets/blob/main/packages/scope/integration.ts
addVitePlugin(somePlugin()) // Fine
addVitePlugin(somePlugin()) // Warn, plugin already installed
Should work even if those are two different integrations
At the moment you have to pass parameters when using an integration created with defineIntegration
because options
isn't optional.
So we want to be able to do this:
integrations: [
myIntegration(),
],
but at the moment have to do this:
integrations: [
myIntegration({}),
],
I wonder if can add a bit of magic using https://github.com/unjs/unctx, basically a wrapper that puts all those arguments in a context so that inside a utility we can just call
const { command } = useHookParams("astro:config:setup")
and that would even allow us to automatically expose args from previous hooks instead of having a let config: AstroConfig
inside the function body
Mostly typing them
import { createResolver, defineIntegration } from 'astro-integration-kit';
export default defineIntegration({
name: 'my-integration',
defaults: {} as any as never,
setup() {
const { resolve } = createResolver(import.meta.url);
return {
'astro:config:setup': async ({ addDevToolbarApp }) => {
addDevToolbarApp(resolve('./plugin.ts'));
},
};
},
});
Here we should be able not to specify defaults
It's possible to give a different virtual module for the same import id depending on whether it's ssr or not, see https://github.com/florian-lefebvre/astro-i18n/blob/main/package/src/integration.ts#L131-L197. That's probably a breaking change but that's a powerful feature.
I was told it's possible to do some black magic here:
Please don't do what I'm about to say, but you can hack around that...
In your postinstall you can check what caused your install by looking at the command that initiated you.
If it was an astro add, daemonize yourself, wait for the command to end and apply that sorting
maybe just re-export https://github.com/patak-dev/vite-plugin-virtual?
Console error presented about deps:
└─┬ astro-integration-kit 0.12.0
└── ✕ unmet peer @astrojs/db@^0.9.0: found 0.10.6
the only side effect of this seems to be lost typing for the extendDb
hook within the main astro integration file.
If i revert the Astrojs/db
package to a 0.9...
version the typing returns.
The broken typing does not appear to effect the actual functionality of the integration as everything else appears to be still functioning as intended
Just started using this to create virtual modules and dts files. This is just an idea, but would make it easier.
// file-factory.ts
import { unindent } from './unindent'
export const fileFactory = () => {
let file = ``
return {
addLines(lines: string) {
file += unindent`${ lines }`
},
text() {
return file
}
}
}
// unindent-ts
export function unindent(strings, ...values) {
const result = [];
const template = strings.reduce((prev, current) => prev + values.shift() + current);
// Find the common indentation
const indentMatch = template.match(/^\n?(\s*)/);
const commonIndent = indentMatch ? indentMatch[1].length : 0;
// Remove common indentation from each line
const lines = template.split('\n');
for (let line of lines) {
result.push(line.slice(commonIndent));
}
// Join the lines back together
return result.join('\n');
}
Basically means you can create virtual modules and dts files much nicer:
"astro:setup:config": () => {
const virtualModule = fileFactory()
virtualModule.addLines(`
export default ${ JSON.stringify({}) }
`)
}
outputs
export default {}
all nicely formatted n stuff so you don't have to worry about indents and messy af dts files if you're trying to dynamically generate
The latest version expects a name
property when creating virtual imports with addVirtualImports()
. This is undocumented, and doesn't make much sense given the imports
object is used to define virtual module names.
Would share a stackblitz, but the TS language server seemed to keep crashing as I tried to repro 😄
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.