Compare commits
58 commits
experiment
...
main
Author | SHA1 | Date | |
---|---|---|---|
bd56e44585 | |||
|
9cb1984c8f | ||
02a980eb79 | |||
|
a238acf0db | ||
|
2595c53f83 | ||
|
155b82cbea | ||
|
12e3cf2f85 | ||
|
e59c210ef4 | ||
|
1fec60d46e | ||
|
8401ac9593 | ||
|
d78e75e9c7 | ||
|
28f272b75b | ||
|
7a7ceceead | ||
|
253ad2e1bc | ||
|
2a238bb835 | ||
|
1c31ef575a | ||
f9c65835fd | |||
|
8ae594d1f5 | ||
bda74f01f9 | |||
|
ddcd451b49 | ||
|
ce5b962e10 | ||
|
c58b597318 | ||
e7c0a762eb | |||
|
01086b6e9b | ||
34eee3d2c1 | |||
|
01b65d337b | ||
c5f9fec9e9 | |||
2b749e4c63 | |||
|
24da21e722 | ||
|
db04ee25e4 | ||
|
c76c016a46 | ||
|
75d349105e | ||
50268b8785 | |||
|
2a9ee3525e | ||
1a1a15692d | |||
|
95a771051f | ||
ca136ebe3b | |||
a5d82807ce | |||
96ac7c0c77 | |||
d3e5a8459f | |||
08b532106d | |||
|
651d77c085 | ||
|
4ff460a7c2 | ||
|
9d216dfa89 | ||
|
c1faeb638f | ||
|
5424854eea | ||
a28e20f7a3 | |||
|
ed7cc9632a | ||
4743f9fbb7 | |||
83cffca379 | |||
|
47bca08a12 | ||
|
8740ef23cc | ||
ed24ac56f3 | |||
|
3bbefc346f | ||
64fe5e795e | |||
|
8d32b568b8 | ||
74b35db6c0 | |||
|
93d1bcce55 |
11 changed files with 763 additions and 721 deletions
30
.github/workflows/app.yml
vendored
30
.github/workflows/app.yml
vendored
|
@ -27,25 +27,23 @@ jobs:
|
|||
semver: ${{ steps.gitversion.outputs.SemVer }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v3.1.11
|
||||
uses: gittools/actions/gitversion/setup@v4.1.0
|
||||
with:
|
||||
versionSpec: "5.x"
|
||||
versionSpec: "6.x"
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v3.1.11
|
||||
with:
|
||||
useConfigFile: true
|
||||
uses: gittools/actions/gitversion/execute@v4.1.0
|
||||
|
||||
build_and_publish:
|
||||
name: Build & Publish
|
||||
runs-on: ubuntu-latest
|
||||
needs: versionize
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Build container images
|
||||
run: |
|
||||
|
@ -73,7 +71,7 @@ jobs:
|
|||
matrix:
|
||||
environment: [ 'prd' ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
sparse-checkout: |
|
||||
infrastructure
|
||||
|
@ -86,13 +84,13 @@ jobs:
|
|||
subscription-id: ${{ secrets.CALQUE_PRD_SUBSCRIPTION_ID }}
|
||||
|
||||
- name: Deploy bicep
|
||||
uses: Azure/cli@v2
|
||||
uses: azure/cli@v2
|
||||
with:
|
||||
azcliversion: 2.66.0
|
||||
inlineScript: |
|
||||
az deployment sub create \
|
||||
--location westeurope \
|
||||
--template-file infrastructure/main.bicep \
|
||||
--parameters infrastructure/params/${{ matrix.environment }}.bicepparam \
|
||||
--parameters version=${{needs.versionize.outputs.semver}} \
|
||||
azcliversion: 2.75.0
|
||||
inlineScript: >-
|
||||
az deployment sub create
|
||||
--location westeurope
|
||||
--template-file infrastructure/main.bicep
|
||||
--parameters infrastructure/params/${{ matrix.environment }}.bicepparam
|
||||
--parameters version=${{needs.versionize.outputs.semver}}
|
||||
--parameters registryUrl=${{ secrets.ACR_LOGIN_SERVER }}
|
|
@ -4,16 +4,17 @@ WORKDIR /usr/src/app
|
|||
FROM base AS install
|
||||
RUN mkdir -p /temp/dev
|
||||
COPY package.json bun.lock /temp/dev
|
||||
COPY patches/ /temp/dev/patches/
|
||||
RUN cd /temp/dev && bun install --frozen-lockfile
|
||||
|
||||
RUN mkdir -p /temp/prod
|
||||
COPY package.json bun.lock /temp/prod/
|
||||
COPY patches/ /temp/prod/patches/
|
||||
RUN cd /temp/prod && bun install --frozen-lockfile --production
|
||||
|
||||
FROM base AS prerelease
|
||||
COPY --from=install /temp/dev/node_modules node_modules
|
||||
COPY . .
|
||||
# RUN echo "SESSION_SECRET=$(head -c 64 /dev/random | base64)" > .env
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV SERVER_PRESET=bun
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
assembly-versioning-scheme: MajorMinorPatch
|
||||
assembly-file-versioning-scheme: MajorMinorPatchTag
|
||||
assembly-informational-format: "{InformationalVersion}"
|
||||
mode: Mainline
|
||||
tag-prefix: "[vV]"
|
||||
continuous-delivery-fallback-tag: ci
|
||||
major-version-bump-message: '\+semver:\s?(breaking|major)'
|
||||
minor-version-bump-message: '\+semver:\s?(feature|minor)'
|
||||
patch-version-bump-message: '\+semver:\s?(fix|patch)'
|
||||
no-bump-message: '\+semver:\s?(none|skip)'
|
||||
legacy-semver-padding: 4
|
||||
build-metadata-padding: 4
|
||||
commits-since-version-source-padding: 4
|
||||
commit-message-incrementing: Enabled
|
||||
branches: {}
|
||||
ignore:
|
||||
sha: []
|
||||
increment: Inherit
|
||||
commit-date-format: yyyy-MM-dd
|
||||
merge-message-formats: {}
|
|
@ -9,7 +9,7 @@ param registryUrl string
|
|||
|
||||
var appName = 'app'
|
||||
|
||||
resource environment 'Microsoft.App/managedEnvironments@2024-03-01' = {
|
||||
resource environment 'Microsoft.App/managedEnvironments@2025-01-01' = {
|
||||
name: 'cea-${context.locationAbbreviation}-${context.environment}-${context.projectName}'
|
||||
location: context.location
|
||||
properties: {
|
||||
|
@ -29,7 +29,7 @@ resource environment 'Microsoft.App/managedEnvironments@2024-03-01' = {
|
|||
}
|
||||
}
|
||||
|
||||
resource app 'Microsoft.App/containerApps@2024-03-01' = {
|
||||
resource app 'Microsoft.App/containerApps@2025-01-01' = {
|
||||
name: 'ca-${context.locationAbbreviation}-${context.environment}-${context.projectName}-app'
|
||||
location: context.location
|
||||
identity: {
|
||||
|
|
|
@ -19,7 +19,7 @@ var context = {
|
|||
deployedAt: deployedAt
|
||||
}
|
||||
|
||||
resource calqueResourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = {
|
||||
resource calqueResourceGroup 'Microsoft.Resources/resourceGroups@2025-04-01' = {
|
||||
name: 'rg-${locationAbbreviation}-${environment}-${projectName}'
|
||||
location: location
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ targetScope = 'resourceGroup'
|
|||
|
||||
param context Context
|
||||
|
||||
resource registry 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
|
||||
resource registry 'Microsoft.ContainerRegistry/registries@2025-04-01' = {
|
||||
name: 'acr${context.locationAbbreviation}${context.environment}${context.projectName}'
|
||||
location: context.location
|
||||
sku: {
|
||||
|
|
49
package.json
49
package.json
|
@ -6,50 +6,50 @@
|
|||
"bun": ">=1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@solid-primitives/clipboard": "^1.6.0",
|
||||
"@solid-primitives/destructure": "^0.2.0",
|
||||
"@solid-primitives/i18n": "^2.2.0",
|
||||
"@solid-primitives/scheduled": "^1.5.0",
|
||||
"@solid-primitives/selection": "^0.1.0",
|
||||
"@solid-primitives/storage": "^4.3.1",
|
||||
"@solid-primitives/timer": "^1.4.0",
|
||||
"@solid-primitives/clipboard": "^1.6.2",
|
||||
"@solid-primitives/destructure": "^0.2.2",
|
||||
"@solid-primitives/i18n": "^2.2.1",
|
||||
"@solid-primitives/scheduled": "^1.5.2",
|
||||
"@solid-primitives/selection": "^0.1.3",
|
||||
"@solid-primitives/storage": "^4.3.3",
|
||||
"@solid-primitives/timer": "^1.4.2",
|
||||
"@solidjs/meta": "^0.29.4",
|
||||
"@solidjs/router": "^0.15.3",
|
||||
"@solidjs/start": "^1.1.0",
|
||||
"@solidjs/start": "^1.1.7",
|
||||
"dexie": "^4.0.11",
|
||||
"flag-icons": "^7.3.2",
|
||||
"flag-icons": "^7.5.0",
|
||||
"iterator-helpers-polyfill": "^3.0.1",
|
||||
"rehype-parse": "^9.0.1",
|
||||
"rehype-remark": "^10.0.0",
|
||||
"rehype-remark": "^10.0.1",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
"remark-parse": "^11.0.0",
|
||||
"remark-rehype": "^11.1.1",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"remark-stringify": "^11.0.0",
|
||||
"sitemap": "^8.0.0",
|
||||
"solid-icons": "^1.1.0",
|
||||
"solid-js": "^1.9.4",
|
||||
"ts-pattern": "^5.6.2",
|
||||
"solid-js": "^1.9.7",
|
||||
"ts-pattern": "^5.7.1",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-find": "^3.0.0",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"vinxi": "^0.5.3"
|
||||
"vinxi": "^0.5.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@happy-dom/global-registrator": "^17.0.3",
|
||||
"@happy-dom/global-registrator": "^18.0.1",
|
||||
"@sinonjs/fake-timers": "^14.0.0",
|
||||
"@solidjs/testing-library": "^0.8.10",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@types/sinonjs__fake-timers": "^8.1.5",
|
||||
"@types/wicg-file-system-access": "^2023.10.5",
|
||||
"@vitest/coverage-istanbul": "3.0.7",
|
||||
"@vitest/coverage-v8": "3.0.7",
|
||||
"bun-types": "^1.2.2",
|
||||
"jsdom": "^26.0.0",
|
||||
"solid-devtools": "^0.33.0",
|
||||
"vite-plugin-solid": "^2.11.2",
|
||||
"@types/wicg-file-system-access": "^2023.10.6",
|
||||
"@vitest/coverage-istanbul": "3.2.4",
|
||||
"@vitest/coverage-v8": "3.2.4",
|
||||
"bun-types": "^1.2.19",
|
||||
"jsdom": "^26.1.0",
|
||||
"solid-devtools": "^0.34.3",
|
||||
"vite-plugin-solid": "^2.11.7",
|
||||
"vite-plugin-solid-svg": "^0.8.1",
|
||||
"vitest": "^3.0.6",
|
||||
"vitest": "^3.2.4",
|
||||
"workbox-window": "^7.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -59,5 +59,8 @@
|
|||
"version": "vinxi version",
|
||||
"test": "vitest --coverage",
|
||||
"test:ci": "vitest run"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"@tanstack/directive-functions-plugin@1.119.2": "patches/@tanstack%2Fdirective-functions-plugin@1.119.2.patch"
|
||||
}
|
||||
}
|
14
patches/@tanstack%2Fdirective-functions-plugin@1.119.2.patch
Normal file
14
patches/@tanstack%2Fdirective-functions-plugin@1.119.2.patch
Normal file
|
@ -0,0 +1,14 @@
|
|||
diff --git a/dist/esm/index.js b/dist/esm/index.js
|
||||
index 813fa63450583316c537cadd46db0c6fce055ac7..205b03d0ae77bfe3ee93f42b0e3d4b5f453502ec 100644
|
||||
--- a/dist/esm/index.js
|
||||
+++ b/dist/esm/index.js
|
||||
@@ -13,6 +13,9 @@ function TanStackDirectiveFunctionsPlugin(opts) {
|
||||
ROOT = config.root;
|
||||
},
|
||||
transform(code, id) {
|
||||
+ if (id.startsWith('/@')) {
|
||||
+ id = `@/${id.slice(2)}`;
|
||||
+ }
|
||||
var _a;
|
||||
const url = pathToFileURL(id);
|
||||
url.searchParams.delete("v");
|
|
@ -12,7 +12,7 @@ interface Contents extends Map<string, Map<string, string>> { }
|
|||
|
||||
export const read = (file: File): Promise<Map<string, string> | undefined> => {
|
||||
switch (file.type) {
|
||||
case 'application/json': return json.load(file.stream());
|
||||
case 'application/json': return json.load(file.text());
|
||||
|
||||
default: return Promise.resolve(undefined);
|
||||
}
|
||||
|
|
|
@ -1,200 +1,20 @@
|
|||
import { decode } from "~/utilities";
|
||||
|
||||
export async function load(stream: ReadableStream<Uint8Array>): Promise<Map<string, string>> {
|
||||
return new Map(await Array.fromAsync(parse(stream), ({ key, value }) => [key, value]));
|
||||
}
|
||||
|
||||
interface Entry {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
(token: Token): State;
|
||||
entry?: Entry
|
||||
}
|
||||
|
||||
const states = {
|
||||
none(): State {
|
||||
return (token: Token) => {
|
||||
if (token.kind === 'braceOpen') {
|
||||
return states.object();
|
||||
}
|
||||
|
||||
return states.none;
|
||||
};
|
||||
},
|
||||
object({ path = [], expect = 'key' }: Partial<{ path: string[], expect: 'key' | 'colon' | 'value' }> = {}): State {
|
||||
return (token: Token) => {
|
||||
switch (expect) {
|
||||
case 'key': {
|
||||
if (token.kind === 'braceClose') {
|
||||
return states.object({
|
||||
path: path.slice(0, -1),
|
||||
expect: 'key',
|
||||
});
|
||||
}
|
||||
else if (token.kind === 'string') {
|
||||
return states.object({
|
||||
path: [...path, token.value],
|
||||
expect: 'colon'
|
||||
});
|
||||
}
|
||||
|
||||
return states.error(`Expected a key, got ${token.kind} instead`);
|
||||
}
|
||||
|
||||
case 'colon': {
|
||||
if (token.kind !== 'colon') {
|
||||
return states.error(`Expected a ':', got ${token.kind} instead`);
|
||||
}
|
||||
|
||||
return states.object({
|
||||
path,
|
||||
expect: 'value'
|
||||
});
|
||||
}
|
||||
|
||||
case 'value': {
|
||||
if (token.kind === 'braceOpen') {
|
||||
return states.object({
|
||||
path,
|
||||
expect: 'key',
|
||||
});
|
||||
}
|
||||
else if (token.kind === 'string') {
|
||||
const next = states.object({
|
||||
path: path.slice(0, -1),
|
||||
expect: 'key',
|
||||
});
|
||||
|
||||
next.entry = { key: path.join('.'), value: decode(token.value) };
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
return states.error(`Invalid value type found '${token.kind}'`);
|
||||
}
|
||||
}
|
||||
|
||||
return states.none();
|
||||
}
|
||||
},
|
||||
error(message: string): State {
|
||||
throw new Error(message);
|
||||
|
||||
return states.none();
|
||||
},
|
||||
} as const;
|
||||
|
||||
async function* parse(stream: ReadableStream<Uint8Array>): AsyncGenerator<any, void, unknown> {
|
||||
let state = states.none();
|
||||
|
||||
for await (const token of tokenize(read(toGenerator(stream)))) {
|
||||
try {
|
||||
state = state(token);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (state.entry) {
|
||||
yield state.entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function* take<T>(iterable: AsyncIterable<T>, numberToTake: number): AsyncGenerator<T, void, unknown> {
|
||||
let i = 0;
|
||||
for await (const entry of iterable) {
|
||||
yield entry;
|
||||
|
||||
i++;
|
||||
|
||||
if (i === numberToTake) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Token = { start: number, length: number } & (
|
||||
| { kind: 'braceOpen' }
|
||||
| { kind: 'braceClose' }
|
||||
| { kind: 'colon' }
|
||||
| { kind: 'string', value: string }
|
||||
);
|
||||
|
||||
async function* tokenize(characters: AsyncIterable<number>): AsyncGenerator<Token, void, unknown> {
|
||||
let buffer: string = '';
|
||||
let clearBuffer = false;
|
||||
let start = 0;
|
||||
let i = 0;
|
||||
|
||||
for await (const character of characters) {
|
||||
if (buffer.length === 0) {
|
||||
start = i;
|
||||
}
|
||||
|
||||
buffer += String.fromCharCode(character);
|
||||
const length = buffer.length;
|
||||
|
||||
if (buffer === '{') {
|
||||
yield { kind: 'braceOpen', start, length };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer === '}') {
|
||||
yield { kind: 'braceClose', start, length };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer === ':') {
|
||||
yield { kind: 'colon', start, length };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer.length > 1 && buffer.startsWith('"') && buffer.endsWith('"') && buffer.at(-2) !== '\\') {
|
||||
yield { kind: 'string', start, length, value: buffer.slice(1, buffer.length - 1) };
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer === ',') {
|
||||
clearBuffer = true;
|
||||
}
|
||||
else if (buffer.trim() === '') {
|
||||
clearBuffer = true;
|
||||
}
|
||||
|
||||
if (clearBuffer) {
|
||||
buffer = '';
|
||||
clearBuffer = false;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
async function* read(chunks: AsyncIterable<Uint8Array>): AsyncGenerator<number, void, unknown> {
|
||||
for await (const chunk of chunks) {
|
||||
for (const character of chunk) {
|
||||
yield character;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function* toGenerator<T>(stream: ReadableStream<T>): AsyncGenerator<T, void, unknown> {
|
||||
const reader = stream.getReader();
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
yield value;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
export async function load(text: Promise<string>): Promise<Map<string, string>> {
|
||||
const source = JSON.parse(await text);
|
||||
const result = new Map();
|
||||
const candidates = Object.entries(source);
|
||||
|
||||
while (candidates.length !== 0) {
|
||||
const [ key, value ] = candidates.shift()!;
|
||||
|
||||
if (typeof value !== 'object' || value === null || value === undefined) {
|
||||
result.set(key, decode(value as string));
|
||||
}
|
||||
else {
|
||||
candidates.unshift(...Object.entries(value).map<[string, any]>(([ k, v ]) => [`${key}.${k}`, v]));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue